gpt4 book ai didi

swift - CABasicAnimation 创建 CALayer 的空默认值副本

转载 作者:搜寻专家 更新时间:2023-11-01 05:53:27 25 4
gpt4 key购买 nike

我有一个绘制径向渐变的自定义 CALayer。除了在动画期间,它工作得很好。似乎 CABasicAnimation 的每次迭代都会创建一个 CALayer 子类的新副本,其中属性的默认值为空:

debug class

在上面的屏幕截图中,您看到 CABasicAnimation 已创建层的新副本并正在更新 gradientOrigin 但没有其他属性随行.

这会导致在动画期间不渲染任何内容。这是一个 GIF:

improper

这是应该的样子:

correct

这是动画代码:

let animation = CABasicAnimation(keyPath: "gradientOrigin")
animation.duration = 2
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
let newOrigin: CGPoint = CGPoint(x: 0, y: triangle.bounds.height/2)
animation.fromValue = NSValue(CGPoint: triangle.gradientLayer.gradientOrigin)
animation.toValue = NSValue(CGPoint: newOrigin)
triangle.gradientLayer.gradientOrigin = newOrigin
triangle.gradientLayer.addAnimation(animation, forKey: nil)

这是自定义 CALayer 代码:

enum RadialGradientLayerProperties: String {
case gradientOrigin
case gradientRadius
case colors
case locations
}

class RadialGradientLayer: CALayer {
var gradientOrigin = CGPoint() {
didSet { setNeedsDisplay() }
}
var gradientRadius = CGFloat() {
didSet { setNeedsDisplay() }
}

var colors = [CGColor]() {
didSet { setNeedsDisplay() }
}

var locations = [CGFloat]() {
didSet { setNeedsDisplay() }
}

override init(){
super.init()
needsDisplayOnBoundsChange = true
}

required init(coder aDecoder: NSCoder) {
super.init()
}

override init(layer: AnyObject) {
super.init(layer: layer)
}

override class func needsDisplayForKey(key: String) -> Bool {
if key == RadialGradientLayerProperties.gradientOrigin.rawValue || key == RadialGradientLayerProperties.gradientRadius.rawValue || key == RadialGradientLayerProperties.colors.rawValue || key == RadialGradientLayerProperties.locations.rawValue {
print("called \(key)")
return true
}
return super.needsDisplayForKey(key)

}

override func actionForKey(event: String) -> CAAction? {
if event == RadialGradientLayerProperties.gradientOrigin.rawValue || event == RadialGradientLayerProperties.gradientRadius.rawValue || event == RadialGradientLayerProperties.colors.rawValue || event == RadialGradientLayerProperties.locations.rawValue {
let animation = CABasicAnimation(keyPath: event)
animation.fromValue = self.presentationLayer()?.valueForKey(event)
return animation
}
return super.actionForKey(event)
}

override func drawInContext(ctx: CGContext) {

guard let colorRef = self.colors.first else { return }

let numberOfComponents = CGColorGetNumberOfComponents(colorRef)
let colorSpace = CGColorGetColorSpace(colorRef)

let deepGradientComponents: [[CGFloat]] = (self.colors.map {
let colorComponents = CGColorGetComponents($0)
let buffer = UnsafeBufferPointer(start: colorComponents, count: numberOfComponents)
return Array(buffer) as [CGFloat]
})

let flattenedGradientComponents = deepGradientComponents.flatMap({ $0 })

let gradient = CGGradientCreateWithColorComponents(colorSpace, flattenedGradientComponents, self.locations, self.locations.count)

CGContextDrawRadialGradient(ctx, gradient, self.gradientOrigin, 0, self.gradientOrigin, self.gradientRadius, .DrawsAfterEndLocation)

}
}

最佳答案

找出答案!

init(layer:) 中,您必须手动将属性值复制到您的类中。这是它的实际效果:

override init(layer: AnyObject) {
if let layer = layer as? RadialGradientLayer {
gradientOrigin = layer.gradientOrigin
gradientRadius = layer.gradientRadius
colors = layer.colors
locations = layer.locations
}
super.init(layer: layer)
}

关于swift - CABasicAnimation 创建 CALayer 的空默认值副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38468515/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com