问题
For an iOS app in Swift, I am using programmatic constraints and would like to add a CAGradientLayer() to a UIView(). Below is my code which doesn't work.
import UIKit
class ViewController: UIViewController {
let animationView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(animationView)
setupAnimationView()
animationView.addGradientLayer()
}
func setupAnimationView() {
animationView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
animationView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
animationView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
animationView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
}
extension UIView {
func addGradientLayer() {
let color1 = UIColor(red: 251/255, green: 55/255, blue: 91/255, alpha: 1.0)
let color2 = UIColor(red: 1.0, green: 70/255, blue: 0, alpha: 1.0)
let gradientLayer = CAGradientLayer()
gradientLayer.name = "gradientLayer"
gradientLayer.frame = self.frame
gradientLayer.colors = [color1.cgColor, color2.cgColor]
self.layer.insertSublayer(gradientLayer, at: 0)
}
}
The issue I am having I believe is related to the fact that I create animationView with programmatic constraints and I then try and add the gradient layer by setting its frame equal to the view of the frame. This code works when I don't use programmatic constraints. Any ideas what I am missing / doing wrong?
回答1:
Any layers that you add to the view will not be managed under AutoLayout and there isn't a way to make this happen.
What you can do is store the layer as a property (perhaps on the view controller).
Then in the method...
override func viewDidLayoutSubviews() {
super.viewDIdLayoutSubviews()
// update the layers frame based on the frame of the view.
}
In this method the view will have it's proper frame so if it has changed you will need to update the layer to have a new frame accordingly.
回答2:
You should change the following line of code:
gradientLayer.frame = self.frame
to:
gradientLayer.frame = bounds
This is important because the frame and the bounds are not using the same coordinate space. Frame is the coordinate space of the superview while bounds is the internal coordinate space of the view.
You can also tell precisely what are the start point and end point of your gradient before adding your gradientLayer to your layer:
gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
layer.addSublayer(gradientLayer)
回答3:
layoutIfNeeded()
should be called to updated views immediately.
animationView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
animationView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
animationView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
animationView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
view.layoutIfNeeded()
来源:https://stackoverflow.com/questions/41566696/how-to-add-a-cagradientlayer-to-a-uiview-when-using-programmatic-constraints