簡體   English   中英

CATransaction:視圖在完成時閃爍

[英]CATransaction: a view flashes on completion

我正在編寫一些復雜的動畫,分為兩個步驟:

  1. 將不需要可見的UIViews不透明度更改為0,並將UIImageView (具有alpha = 1 )移動到另一個CGPoint (位置)。
  2. 將另一個UIView的不透明度更改為1,並將上一步的UIImageView的不透明度更改為0,然后在完成此步驟的動畫后,從超級視圖中刪除UIImageView

我這樣做是這樣的:

第一步是在沒有顯式CATransaction的情況下完成的。 這兩個動畫的beginTime設置為CACurrentMediaTime() 我在layer.addAnimation(...)調用之后layer.addAnimation(...)將更改應用於視圖。 這里一切都很好。

第二步實現中,我首先調用CATransaction.begin() 在對CATransaction begin/commit調用中,我創建了2個CABasicAnimations並將其添加到2個不同的層:一個用於將不透明度從0更改為1(對於UIView ),一個用於將不透明度從1更改為0(對於UIImageView )。 這兩個動畫的beginTime設置為CACurrentMediaTime() + durationOfThePreviousStep

CATransaction.begin()我調用CATransaction.setCompletionBlock({...}) ,在此完成塊中,我將更改應用於這兩個視圖:設置它們的新alpha並從超級視圖中刪除UIImageView

問題是,在整個動畫的結尾,具有alpha動畫的UIView閃爍為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()

編輯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()

可能是因為timeView有一個UITextField和一個帶有4 timeView視圖的UIScrollView 我試圖取代timeView與快照timeViewUIImageView ),但是這並沒有幫助。

編輯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()

僅查看您的代碼,我希望它會閃爍。 為什么? 因為您將timeView的圖層的不透明度設置為從0到1,但是您尚未設置為1(在完成處理程序中除外,這將在以后發生)。 因此,我們將表示層的動畫從0設置為1,然后動畫結束,這表明真實層的不透明度始終為0。

因此,在動畫開始timeView之前,將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()

關於您的代碼,還有其他一些事情我覺得很奇怪。 以這種方式使用事務完成塊有些冒險; 我不明白為什么不給動畫委托。 另外,您將多次重復使用alphaAnimation 我不推薦那樣。 如果我是你,我將為每個動畫創建一個新的CABasicAnimation。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM