使用编程约束时如何将 CAGradientLayer 添加到 UIView

How to add a CAGradientLayer to a UIView when using programmatic constraints

对于 Swift 中的 iOS 应用程序,我正在使用编程约束并想将 CAGradientLayer() 添加到 UIView()。下面是我的代码,它不起作用。

   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)
       }
   }

我认为我遇到的问题与以下事实有关:我创建了带有编程约束的 animationView,然后我尝试通过将其框架设置为等于框架视图来添加渐变层。当我不使用编程约束时,此代码有效。知道我遗漏了什么/做错了什么吗?

layoutIfNeeded() 应立即调用以更新视图。

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()

您应该更改以下代码行:

gradientLayer.frame = self.frame

至:

gradientLayer.frame = bounds

这很重要,因为框架和边界未使用相同的坐标 space。 Frame 是父视图的坐标 space 而 bounds 是视图的内部坐标 space。

在将 gradientLayer 添加到图层之前,您还可以准确地知道渐变的起点和终点是什么:

gradientLayer.startPoint = CGPoint(x: 0.0, y: 0.5)
gradientLayer.endPoint = CGPoint(x: 1.0, y: 0.5)
layer.addSublayer(gradientLayer)

您添加到视图中的任何图层都不会在 AutoLayout 下进行管理,并且没有办法实现这一点。

您可以将层存储为 属性(可能在视图控制器上)。

然后在方法中...

override func viewDidLayoutSubviews() {
    super.viewDIdLayoutSubviews()
    // update the layers frame based on the frame of the view.
}

在这种方法中,视图将具有适当的框架,因此如果它发生变化,您将需要相应地更新图层以具有新框架。