2017-02-28 55 views
2

我正在使用關鍵幀爲標籤創建一個簡單的從左到右的動畫,但是當動畫重複時,延遲被忽略。帶重複和延遲的animateKeyframes無法按預期工作

第一次執行時,3秒的延遲有效,但是當動畫重複時,延遲被忽略。這會導致動畫在結束後立即重新開始。

UIView.animateKeyframes(withDuration: 10, delay: 3, options: [.calculationModePaced, .repeat], animations: { 
    let xDist = self.Label_ArtistAlbum2.frame.origin.x 

    UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.1, animations: { 
     self.Label_ArtistAlbum2.frame.origin.x = self.Label_ArtistAlbum2.frame.origin.x - (xDist * 0.1) 
    }) 

    UIView.addKeyframe(withRelativeStartTime: 0.9, relativeDuration: 0.1, animations: { 
     self.Label_ArtistAlbum2.frame.origin.x = 0 
    }) 
}, completion: nil) 

我試圖在最後增加一個額外的關鍵幀,然而,這甚至已經改變了其時間沒有影響:

UIView.animateKeyframes(withDuration: 10, delay: 3, options: [.calculationModePaced, .repeat], animations: { 
    let xDist = self.Label_ArtistAlbum2.frame.origin.x 

    UIView.addKeyframe(withRelativeStartTime: 0.0, relativeDuration: 0.1, animations: { 
     self.Label_ArtistAlbum2.frame.origin.x = self.Label_ArtistAlbum2.frame.origin.x - (xDist * 0.1) 
    }) 

    UIView.addKeyframe(withRelativeStartTime: 0.1, relativeDuration: 0.7, animations: { 
     self.Label_ArtistAlbum2.frame.origin.x = 0 
    }) 

    //attempted pause - does not appear to work perhaps since the position is unchanged? 
    UIView.addKeyframe(withRelativeStartTime: 0.8, relativeDuration: 0.2, animations: { 
     self.Label_ArtistAlbum2.frame.origin.x = 0 
    }) 
}, completion: nil) 

如果延遲不會與動畫的其餘部分一起被重複,如何在整個動畫重複之前創建暫停?

回答

1

我已經做了很多測試,在這個問題上並發現我認爲是問題所在。

我認爲曲線的動畫選項是我的問題。 在我的情況選擇

calculationModePaced

有重新計算我的關鍵幀參數,不能保證擊中任何人,除了開頭和結尾的效果。所有中間關鍵幀都成爲'建議'。 最終不能創建暫停,因爲關鍵幀在重新計算時「消耗殆盡」,並且不能獨立運行。

我更改爲calculationModeLinear並獲得了我期望的關鍵幀和暫停。 但是,它是一帆風順的,我想,所以我將必須繼續擺弄......

蘋果的文檔是在這裏 - 他們是描述性的,但真的可以使用一些圖形和/或例子: https://developer.apple.com/reference/uikit/uiview?language=swift

曲線的好圖可以在這裏找到:https://www.shinobicontrols.com/blog/ios7-day-by-day-day-11-uiview-key-frame-animations

0

我有一個動畫加載視圖類似的問題。我解決了它這種方式:

我創建了一個枚舉動畫中的步驟

private enum TriangleToAnimate { 
    case one 
    case two 
    case three 
    case pause 
} 

我有我的變量

private var triangleViewToFireCount = TriangleToAnimate.one 
var triangle1View : TriangleView 
var triangle2View : TriangleView 
var triangle3View : TriangleView 

我啓動一個定時器運行每個動畫

override init(frame: CGRect) { 
    Timer.scheduledTimer(timeInterval: 0.33, target: self, selector: #selector(LoadingView.timerFire), userInfo: nil, repeats: true) 
} 

對於選擇器我有一個消防方法。在該方法中,我爲每個的枚舉情況下,開關

func timerFire(){ 
    let anim = createAnimation() 
    switch triangleViewToFireCount { 
    case .one: 
     triangle1View.layer.add(anim, forKey: "transform") 
     triangleViewToFireCount = .two 
    case .two: 
     triangle2View.layer.add(anim, forKey: "transform") 
     triangleViewToFireCount = .three 
    case .three: 
     triangle3View.layer.add(anim, forKey: "transform") 
     triangleViewToFireCount = .pause 
    default: 
     triangleViewToFireCount = .one 
    } 
} 

我這是怎麼創造的動畫作爲一個關鍵幀代碼

func createAnimation() -> CAKeyframeAnimation{ 
    let tr = CATransform3DIdentity 
    let orignalScale = CATransform3DScale(tr, 1, 1, 1) 
    let doubleScale = CATransform3DScale(tr, 2, 2, 1) 
    let keyAn = CAKeyframeAnimation(keyPath: "transform") 
    keyAn.keyTimes = [0, 0.1, 0.6] 
    keyAn.duration = 1 
    keyAn.values = [orignalScale,doubleScale,orignalScale] 
    keyAn.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) 
    return keyAn 
}