Twitter iOS App 啟動動畫的實現

Welkinx發表於2016-10-20

當我第一次開啟 twitter 的時候,就被它的啟動動畫驚豔到了。然而分析一下這個動畫其實也不難實現,於是趕緊做一個出來看看。

整個動畫效果能夠拆分為以下幾步:

  • 佈置一個與 LaunchScreen 相同的介面
  • 讓檢視中間的 Logo 先縮小後放大直至蓋滿整個螢幕
  • Logo 在放大過程中逐漸變透明
  • Initial View Controller 的內容稍微放大後恢復原狀

拆分完之後就好辦咯,一步步來實現吧~

先布個介面吧

由於後面需要讓 logo 變透明,我們選擇用 mask 來實現。

let logoLayer = CALayer()
logoLayer.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
logoLayer.position = view.center
logoLayer.contents = UIImage(named: "logo")?.cgImage
view.layer.mask = logoLayer

好了,小鳥出來了。

但一開始這個 logo 並不是透明的,於是先在其上蓋一層白色的 view,並改一下背景顏色吧。

let shelterView = UIView(frame: view.frame)
shelterView.backgroundColor = .white
view.addSubview(shelterView)

window!.backgroundColor = UIColor(red: 29 / 255.0, green: 161 / 255.0, blue: 242 / 255.0, alpha: 1)

棒,第一步完成。

那接著做 Logo 的縮小放大吧

這裡我們用 CAKeyframeAnimation,讓這個縮放動作一氣呵成。設定好開始時間、持續時間和各個關鍵幀,最後讓它保持動畫最後的狀態。

let logoAnimation = CAKeyframeAnimation(keyPath: "bounds")
logoAnimation.beginTime = CACurrentMediaTime() + 1
logoAnimation.duration = 1
logoAnimation.keyTimes = [0, 0.4, 1]
logoAnimation.values = [NSValue(cgRect: CGRect(x: 0, y: 0, width: 100, height: 100)),
                    NSValue(cgRect: CGRect(x: 0, y: 0, width: 85, height: 85)),
                    NSValue(cgRect: CGRect(x: 0, y: 0, width: 4500, height: 4500))]
logoAnimation.timingFunctions = [CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut),
                             CAMediaTimingFunction(name: kCAMediaTimingFunctionDefault)]
logoAnimation.isRemovedOnCompletion = false
logoAnimation.fillMode = kCAFillModeForwards
logoLayer.add(logoAnimation, forKey: "zoomAnimation")

又好了。

順道把 Logo 透明也帶上

這個算好漸變透明的時間就好。

UIView.animate(withDuration: 0.3, delay: 1.4, options: .curveLinear, animations: {
    shelterView.alpha = 0
}) { (_) in
    shelterView.removeFromSuperview()
    view.layer.mask = nil
}

最後,讓初始介面顛一下

道理跟第二步相同,就不說了~

let mainViewAnimation = CAKeyframeAnimation(keyPath: "transform")
mainViewAnimation.beginTime = CACurrentMediaTime() + 1.1
mainViewAnimation.duration = 0.6
mainViewAnimation.keyTimes = [0, 0.5, 1]
mainViewAnimation.values = [NSValue(caTransform3D: CATransform3DIdentity),
                            NSValue(caTransform3D: CATransform3DScale(CATransform3DIdentity, 1.1, 1.1, 1)),
                            NSValue(caTransform3D: CATransform3DIdentity)]
view.layer.add(mainViewAnimation, forKey: "transformAnimation")
view.layer.transform = CATransform3DIdentity

Done.

需要完整程式碼的可以來這裡下~

Github: TwitterLauncher

相關文章