Ran*_*dex 1 core-animation uiview cabasicanimation ios catransaction
我正在编写一个有点复杂的动画,分两步进行:
UIViews
将不需要可见的不透明度更改为 0 ,并将 a UIImageView
(具有alpha = 1
)移动到另一个CGPoint
(位置)。UIView
不透明度更改为0,然后在这一步的动画完成后,从superview中删除。UIImageView
UIImageView
我是这样做的:
第一步是在没有显式 CATransaction 的情况下完成的。这两个动画刚刚beginTime
设置为CACurrentMediaTime()
。我在layer.addAnimation(...)
通话后立即对视图进行更改。这里一切正常。
在第二步CATransaction.begin()
实施中,我在开始时调用。在内部begin/commit
调用中,CATransaction
我创建并添加 2CABasicAnimations
到 2 个不同的层:一层用于将不透明度从 0 更改为 1(对于UIView
),一层用于将不透明度从 1 更改为 0(对于UIImageView
)。两个动画都beginTime
设置为CACurrentMediaTime() + durationOfThePreviousStep
。
在CATransaction.begin()
我调用CATransaction.setCompletionBlock({...})
, 并在此完成块中,我对这两个视图应用更改:设置它们的新 alpha 并UIImageView
从超级视图中删除。
问题是,在整个动画结束时,UIView
alpha 动画为 1 闪烁,这意味着它的 alpha 设置回 0(尽管我在完成块中将其 alpha 设置为 1),紧接着完成块执行后其 alpha 再次上升至 1。
那么问题来了,如何消除这种闪烁呢?也许这个动画可以以更好的方式完成?
PS 我没有使用UIView
动画,因为我对这些动画的自定义计时函数感兴趣。
编辑1:这是代码。我已经删除了UIImageView
Alpha 动画,因为它并不是真正必要的。
var totalDuration: CFTimeInterval = 0.0
// Alpha animations.
let alphaAnimation = CABasicAnimation()
alphaAnimation.keyPath = "opacity"
alphaAnimation.fromValue = 1
alphaAnimation.toValue = 0
alphaAnimation.beginTime = CACurrentMediaTime()
alphaAnimation.duration = 0.15
let alphaAnimationName = "viewsFadeOut"
view1.layer.addAnimation(alphaAnimation, forKey: alphaAnimationName)
view1.alpha = 0
view2.layer.addAnimation(alphaAnimation, forKey: alphaAnimationName)
view2.alpha = 0
view3.layer.addAnimation(alphaAnimation, forKey: alphaAnimationName)
view3.alpha = 0
view4.layer.addAnimation(alphaAnimation, forKey: alphaAnimationName)
view4.alpha = 0
// Image View moving animation.
// Add to total duration.
let rect = /* getting rect */
let newImagePosition = view.convertPoint(CGPoint(x: CGRectGetMidX(rect), y: CGRectGetMidY(rect)), fromView: timeView)
let imageAnimation = CABasicAnimation()
imageAnimation.keyPath = "position"
imageAnimation.fromValue = NSValue(CGPoint: imageView!.layer.position)
imageAnimation.toValue = NSValue(CGPoint: newImagePosition)
imageAnimation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)
imageAnimation.beginTime = CACurrentMediaTime()
imageAnimation.duration = 0.3
imageView!.layer.addAnimation(imageAnimation, forKey: "moveImage")
imageView!.center = newImagePosition
totalDuration += imageAnimation.duration
// Time View alpha.
CATransaction.begin()
CATransaction.setCompletionBlock {
self.timeView.alpha = 1
self.imageView!.removeFromSuperview()
self.imageView = nil
}
let beginTime = CACurrentMediaTime() + totalDuration
let duration = 0.3
alphaAnimation.fromValue = 0
alphaAnimation.toValue = 1
alphaAnimation.beginTime = beginTime
alphaAnimation.duration = duration
timeView.layer.addAnimation(alphaAnimation, forKey: "timeViewFadeIn")
/* imageView alpha animation is not necessary, so I removed it */
CATransaction.commit()
Run Code Online (Sandbox Code Playgroud)
编辑2:导致问题的代码段:
CATransaction.begin()
CATransaction.setCompletionBlock {
self.timeView.alpha = 1
}
let duration = 0.3
let alphaAnimation = CABasicAnimation()
alphaAnimation.keyPath = "opacity"
alphaAnimation.fromValue = 0.0
alphaAnimation.toValue = 1.0
alphaAnimation.duration = duration
timeView.layer.addAnimation(alphaAnimation, forKey: "timeViewFadeIn")
CATransaction.commit()
Run Code Online (Sandbox Code Playgroud)
也许问题是因为timeView
有 aUITextField
和 aUIScrollView
有 4 个子视图。我尝试用( )timeView
的快照替换,但这没有帮助。timeView
UIImageView
编辑3:新代码。使用这段代码,timeView
总是有alpha = 1
,并且它也从 0 到 1 进行动画处理。
CATransaction.begin()
CATransaction.setCompletionBlock {
self.imageView!.removeFromSuperview()
self.imageView = nil
}
let alphaAnimation = CABasicAnimation()
alphaAnimation.keyPath = "opacity"
alphaAnimation.fromValue = 0.0
alphaAnimation.toValue = 1.0
alphaAnimation.duration = 0.3
alphaAnimation.beginTime = beginTime
timeView.layer.addAnimation(alphaAnimation, forKey: "timeViewFadeIn")
timeView.alpha = 1.0
CATransaction.commit()
Run Code Online (Sandbox Code Playgroud)
只要看看你的代码,我就希望它会闪烁。为什么?因为您已将动画timeView
层的不透明度从 0 设置为 1,但尚未将其设置为 1(除了在完成处理程序中,这将在稍后发生)。因此,我们将表示层从 0 动画到 1,然后动画结束,显示真实层的不透明度始终为 0。
因此,timeView
在动画开始之前将图层的不透明度设置为 1。另外,由于您使用的是延迟的beginTime
,因此您需要将动画设置fillMode
为"backwards"
。
通过将您的测试代码修改为独立的并且看起来像这样,我能够获得良好的结果;有延迟,视图淡入,最后没有闪光:
CATransaction.begin()
let beginTime = CACurrentMediaTime() + 1.0 // arbitrary, just testing
let alphaAnimation = CABasicAnimation()
alphaAnimation.keyPath = "opacity"
alphaAnimation.fromValue = 0.0
alphaAnimation.toValue = 1.0
alphaAnimation.duration = 1.0 // arbitrary, just testing
alphaAnimation.fillMode = "backwards"
alphaAnimation.beginTime = beginTime
timeView.layer.addAnimation(alphaAnimation, forKey: "timeViewFadeIn")
timeView.layer.opacity = 1.0
CATransaction.commit()
Run Code Online (Sandbox Code Playgroud)
我觉得你的代码还有一些其他的事情很奇怪。以这种方式使用交易完成块是有一定风险的;我不明白你为什么不给你的动画一个委托。此外,您还alphaAnimation
多次重复使用;我不能推荐这样做。如果我是你,我会为每个动画创建一个新的 CABasicAnimation。
归档时间: |
|
查看次数: |
2948 次 |
最近记录: |