I have applied a gradient to a custom UIView by adding a CAGradientLayer. While this works fine there is small glitch when rotating the device and the view + layer with it. For a short moment the layer does not cover the complete view but the views / background is visible instead. How can this be avoided?
Code:
class BackgroundView: UIView {
private let gradient : CAGradientLayer = CAGradientLayer()
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
func commonInit() {
gradient.colors = [UIColor.white.cgColor, UIColor.black.cgColor]
self.layer.insertSublayer(gradient, at: 0)
}
// Option 1: Adjust layer on sublayer layout
override func layoutSublayers(of layer: CALayer) {
super.layoutSublayers(of: layer)
gradient.frame = self.bounds
}
// Option 2: Adjust layer on subview layout
override func layoutSubviews() {
super.layoutSubviews()
gradient.frame = self.bounds
}
// Option 3: Adjust layer on trait collection change
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
super.traitCollectionDidChange(previousTraitCollection)
gradient.frame = self.bounds
}
}
The result is exactly the same, no matter if Option1 or Option2 is jused, or both. In all cases the layer is correctly resized during rotation to its new, final size/bounds but not in the same way as the view itself. So the view and its background become visible for a short moment. How to avoid this?
The gradient should cover the whole view at all times.
I found several question on how to rotate a layer with its view. However, all answers provide on of the options I tried. I am doing something wrong or is this glitch normal?
EDIT: Updating the gradient bounds on a trait collection change has the same effect.
You can override the
layerClassso the view's "base layer" is aCAGradientLayerinstead of adding one as a sublayer.Take a look at this: