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:
The gradient, and the GradientView, will then appear where you expect them.