如何在使用程序化约束时将CAGradientLayer添加到UIView

对于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的事实有关,然后我尝试通过将其框架设置为等于框架的视图来添加渐变图层。 当我不使用程序化约束时,此代码有效。 我有什么想法/错误?

您添加到视图中的任何图层都不会在AutoLayout下进行管理,并且无法实现此目的。

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

然后在方法中……

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

在此方法中,视图将具有正确的框架,因此如果它已更改,则需要更新图层以相应地设置新框架。

您应该更改以下代码行:

 gradientLayer.frame = self.frame 

至:

 gradientLayer.frame = bounds 

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

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

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

应立即调用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()