今天我們要來實現上面這一個簡單的轉場動畫,非常的容易實現,剛開始接觸轉場動畫的同學可以拿來練手一下。
這一篇文章將不會很仔細地說明轉場動畫的邏輯,所以如果還不了解如何自定義轉場動畫或者它的原理,
請跳轉至:Swift 自订义非交互转场动画(Custom Transition ViewController)。
準備動作
我們通過實現UINavigationControllerDelegate來自定義Navigation的轉場方法,並且告訴Transition我們進行的是push還是pop,
並且告知是哪一個按鈕被點了(selectedView)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { if selectedView != nil { transition.selectedView = selectedView! } if fromVC is MenuViewController { transition.isPush = true } else { transition.isPush = false } return transition } |
創建SKDiffusionTransition.swift來實現轉場動畫協議的方法
1 2 3 4 5 |
// 動畫時間 func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval // 具體動畫內容 func animateTransition(using transitionContext: UIViewControllerContextTransitioning) |
在animateTransition中準備好fromView, toView, containerView
1 2 3 4 5 6 7 8 9 10 |
// from view let fromVC = transitionContext.viewController(forKey: .from)! let fromView = fromVC.view! // to view let toVC = transitionContext.viewController(forKey: .to)! let toView = toVC.view! // container view let containerView = transitionContext.containerView |
實現Push展開動畫
當使用者點下黃色按鈕時,我們將toView從按鈕的位置展開至全畫面。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
if isPush { containerView.addSubview(fromView) toView.frame = selectedView.frame toView.clipsToBounds = true containerView.addSubview(toView) UIView.animate(withDuration: 2, animations: { toView.frame = UIScreen.main.bounds }, completion: { finished in fromView.removeFromSuperview() transitionContext.completeTransition(true) }) } |
實現Pop收縮動畫
將充滿畫面的圖,縮小到之前所點的按鈕位置。
這裡是通過遮罩層(Mask)來做的,不過不太清楚的是,為什麼打算從SuperView移出maskView的時候會Crash,需要再研究下引用關係。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
let maskView = UIView(frame: fromView.frame) maskView.backgroundColor = UIColor.black maskView.clipsToBounds = true containerView.addSubview(toView) containerView.addSubview(maskView) containerView.addSubview(fromView) fromView.mask = maskView UIView.animate(withDuration: 0.2, animations: { maskView.frame = self.selectedView.frame maskView.layer.cornerRadius = self.selectedView.frame.width/2 }, completion: { finished in // don't know why it will crash // maskView.removeFromSuperview() fromView.removeFromSuperview() transitionContext.completeTransition(true) }) |
如果在自定義轉場動畫的時候發現畫面卡住不動,看看是不是忘記使用下面的方法通知系統完成動畫了,
或者是忘記將哪一個畫面從containerView中移除了。
1 |
transitionContext.completeTransition(true) |
推薦和參考
- 歡迎分享本文「Swift實現Menu擴散轉場動畫」連結 https://ios.devdon.com/archives/547
- 本文在Github上相關的SourceCode。
- 了解自定義轉場動畫:Swift 自订义非交互转场动画(Custom Transition ViewController)