我想要动画一个CALAyer,使它看起来像是从任何地方出现。我想我可以首先将图层的转换设置为“缩放为x: 0,y: 0”。然后做一个动画,将转换设置为“缩放为x: 1,y: 1",这是身份。我以为这会使图层看起来从零开始扩大。然而,当我试图实现这一点时,该层立即出现,没有动画。
MCVE:
class MyView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
commonInit()
}
func commonInit() {
backgroundColor = .clear
clipsToBounds = false
setupLayers()
}
var squareLayer: CAShapeLayer!
private func setupLayers() {
layer.sublayers?.forEach { $0.removeFromSuperlayer() }
squareLayer = CAShapeLayer()
layer.addSublayer(squareLayer)
}
override func layoutSubviews() {
super.layoutSubviews()
drawLayers()
}
func drawLayers() {
squareLayer.fillColor = UIColor.red.cgColor
squareLayer.path = UIBezierPath(rect: bounds).cgPath
squareLayer.frame = bounds
}
}然后在我的VC里:
@IBAction func click() {
myView = MyView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
view.addSubview(myView)
myView.drawLayers()
myView.squareLayer.setAffineTransform(.init(scaleX: 0, y: 0))
CATransaction.begin()
CATransaction.setAnimationDuration(1)
self.myView.squareLayer.setAffineTransform(.init(scaleX: 1, y: 1))
CATransaction.commit()
}我认为这是因为第一个setAffineTransform调用也是动画的(我不知道为什么会产生效果,但我怀疑这可能会产生影响),所以我尝试将第二个调用移到完成块中:
@IBAction func click() {
myView = MyView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
view.addSubview(myView)
myView.drawLayers()
CATransaction.begin()
CATransaction.setCompletionBlock {
CATransaction.begin()
CATransaction.setAnimationDuration(1)
self.myView.squareLayer.setAffineTransform(.init(scaleX: 1, y: 1))
CATransaction.commit()
}
myView.squareLayer.setAffineTransform(.init(scaleX: 0, y: 0))
CATransaction.commit()
}但是,输出是相同的。另一方面,如果我在第一个setAffineTransform调用之后等待一段时间,那么它可以工作:
@IBAction func click() {
myView = MyView(frame: CGRect(x: 100, y: 100, width: 100, height: 100))
view.addSubview(myView)
myView.drawLayers()
myView.squareLayer.setAffineTransform(.init(scaleX: 0, y: 0))
DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
CATransaction.begin()
CATransaction.setAnimationDuration(1)
self.myView.squareLayer.setAffineTransform(.init(scaleX: 1, y: 1))
CATransaction.commit()
}
}我不认为这是我应该解决这个问题的方式。在此期间,可能会调用一些生命周期方法(我不知道哪个方法),而我应该做的是在该生命周期方法之后执行第二个setAffineTransform调用.(?)
我知道我可以用CABasicAnimation代替,但是我不喜欢使用委托来检测动画的结束。这使得许多事情对我来说非常麻烦。由于延迟0.1秒工作,这不可能是不可能的CATransaction,对吗?
如何使用动画使CALayer出现?
发布于 2021-10-04 08:04:02
另一方面,
,如果我再等一会儿
是这样的。一个层必须是呈现树的一部分才能被动画化,所以您不能添加一个层并将它作为同一事务的一部分来动画。因此,异步调用等待当前事务提交,下一个事务在附加动画之前启动,实际上是一个完全正确的解决方案。
另一种可能是在添加层之后调用CATransaction.flush();这有效地提前提交了当前事务。
https://stackoverflow.com/questions/69432571
复制相似问题