I made a custom view which has CAGradientLayer
as a layer, and I added this view on the other view with bottom anchor. It was just very simple auto layout constraint with bottom, leading, trailing and height constraints. However the bottom constraint doesn't work and it is always at the top(y == 0).
class GradientView: UIView {
override class var layerClass: AnyClass { CAGradientLayer.self }
private var gradientLayer: CAGradientLayer { layer as! CAGradientLayer }
var colors: [UIColor] = [.clear, .white] { didSet { setNeedsLayout() } }
var locations: [NSNumber] = [0, 1] { didSet { setNeedsLayout() } }
override func layoutSubviews() {
super.layoutSubviews()
gradientLayer.frame = bounds
gradientLayer.colors = colors.map { $0.cgColor }
gradientLayer.locations = locations
}
}
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let gradient = GradientView()
gradient.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(gradient)
gradient.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
gradient.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
gradient.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
gradient.heightAnchor.constraint(equalToConstant: 100).isActive = true
}
}
The result is like below. The gradient view is at the top, not bottom of the view.
I tried almost everything I could imagine and finally removed the layerClass
and added the CAGradientLayer
as a sublayer, and the constraint started working.
Is there anything I missed to override layerClass
or it is kind of a bug?
You are the one breaking autolayout. Delete this line:
gradientLayer.frame = bounds
The gradient, and the GradientView, will then appear where you expect them.