我无法在其中一个视图上设置图层动画.我搜索了这个问题,但只能使用CATransaction找到答案,假设我知道其边界的fromValue和toValue.我在tableHeader中有一个视图,在单击时调整自身大小.这个视图
          为了确保图层整体得到正确的大小(在初始化/加载/屏幕旋转等),我被告知这样做:
override func layoutSubviews() {
    super.layoutSubviews()
    gradientLayer.frame = backgroundView.bounds
} 
 它每次都会获得正确的大小,但它从未动画过.
要做我的视图动画,我这样做:
self.someLabelHeightConstraint.constant = someHeight
UIView.animate(withDuration: 0.3, animations: { [weak self] in                
    self?.layoutIfNeeded()
}) 
 这是完美的,但我假设layoutIfNeeded()在某个时刻调用layoutSubviews,我认为这将破坏我添加到块中的任何CALayer动画.
如您所见,我只更改视图中视图上的约束常量,因此实际上我不知道动画完成时实际标题视图的大小.我可以做一些数学计算它会是什么,但这似乎是不必要的..
有没有更好的方法来做到这一点?
在动画期间有更新方法来更新子层的框架,但最优雅的解决方案是让UIKit为您处理这个问题.创建一个子类UIView,其layerClass是CAGradientLayer.创建视图后,将为您创建CAGradientLayer.当您为视图的框架设置动画时,渐变图层会为您优雅地设置动画. 
  
  
 @IBDesignable
public class GradientView: UIView {
    @IBInspectable public var startColor: UIColor = .white { didSet { updateColors() } }
    @IBInspectable public var endColor:   UIColor = .black { didSet { updateColors() } }
    override open class var layerClass: AnyClass { return CAGradientLayer.self }
    override public init(frame: CGRect = .zero) {
        super.init(frame: frame)
        config()
    }
    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        config()
    }
    private func config() {
        updateColors()
    }
    private func updateColors() {
        let gradientLayer = layer as! CAGradientLayer
        gradientLayer.colors = [startColor.cgColor, endColor.cgColor]
    }
} 
 注意,我已经制作了这个@IBDesignable,所以你可以将它放在一个框架目标中,然后在IB中使用它,但这取决于你.这不是必需的.主要问题是覆盖layerClass,以便UIKit在动画视图时处理图层的动画.

