ViewController
當中,並分別命名爲centerXAlign
與centerYAlign
button
viewWillAppear
與viewDidAppear
準備完成後,代碼部分以下所示:swift
import UIKit class ViewController: UIViewController { @IBOutlet weak var centerXAlign: NSLayoutConstraint! @IBOutlet weak var centerYAlign: NSLayoutConstraint! @IBOutlet weak var button: UIButton! // ... override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) } override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) } }
根據以前的準備,咱們能夠開始進行動畫效果的編寫。爲了讓標籤實現水平移入的動畫效果,咱們須要改變標籤的初始位置到屏幕的外面。以下所示:app
override func viewWillAppear(animated: Bool) { super.viewWillAppear(animated) centerXAlign.constant -= view.bounds.width }
viewWillAppear
方法用於執行在視圖尚未顯現,可是將要顯現時候,須要進行的操做。.constant
爲約束的值。view.bounds
表示當前視圖的邊界。ide
注意:上面代碼中
centerXAlign.constant
減去的內容並非其精確的須要減去的數值,只是出於方便的考慮才直接使用視圖的寬度進行設置。學習
在視圖將要載入時,將要顯示的內容移除屏幕後,咱們須要在視圖完成顯示時,再將屏幕外的標籤移動進來。因爲想要達到水平移動的效果,咱們只須要改變標籤水平約束的值就能夠了。以下所示:動畫
override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) UIView.animateWithDuration(1.0, delay: 0.0, options: UIViewAnimationOptions.CurveEaseOut, animations: { self.centerXAlign.constant += self.view.bounds.width self.view.layoutIfNeeded() }, completion: nil) }
咱們設置標籤移入動畫的持續時間爲1秒,延遲0秒執行,使用.CurveEaseOut
效果執行動畫。動畫的內容爲對標籤的約束執行「加」操做,並調用self.view.layoutIfNeeded()
方法,使動畫效果生效。.net
此時,咱們執行程序將會發現,標籤從屏幕的右方水平移入。設計
注意:全部的動畫效果,都是經過改變UIView實例的以下屬性來進行的。code
- center —— 中心
- alpha —— 透明度
- frame —— 邊框
- bounds —— 約束
- transform —— 切換
- backgroundColor —— 背景色
- contentStretch —— 內容縮放
以前咱們已經完成對標籤水平移入的操做,這裏咱們爲以前添加的按鈕添加彈性動畫的效果。按鈕將在標籤水平移入後,執行彈性動畫。具體實現以下所示:orm
override func viewDidAppear(animated: Bool) { super.viewDidAppear(animated) // ... let bounds = self.button.bounds UIView.animateWithDuration(2.0, delay: 1.2, usingSpringWithDamping: 0.1, initialSpringVelocity: 100.0, options: nil, animations: { self.button.bounds = CGRect(x: bounds.origin.x - 80, y: bounds.origin.y, width: bounds.size.width + 160, height: bounds.height) }, completion: nil) }
在上面的代碼中,咱們經過使用一個新的矩形描述改變按鈕的邊界值,從而實現對按鈕大小改變的彈性動畫。blog
View Controller
UIViewController
的子類,「CustomPresentAnimationController.swift」、「CustomDismissAnimationController.swift」「CustomNavigationAnimationController.swift」、「CustomNavigationAnimationController.swift」爲NSObject
的子類。View Controller
的類爲ActionViewController
Action View Controller
的背景色,並拖入一個按鈕,修改按鈕標題爲「Dismiss」Action View Controller
的Segue,設置Segue的類型爲Present Modal
,用於彈出Action View Controller
注意:
- 在向項目添加文件的時候,要注意不要選擇了OSX應用類型。
向CustomPresentAnimationController.swift文件添加以下代碼。
import UIKit class CustomPresentAnimationController: NSObject, UIViewControllerAnimatedTransitioning { func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval { return 5.0 } func animateTransition(transitionContext: UIViewControllerContextTransitioning) { let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)! let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)! let finalFrameForVC = transitionContext.finalFrameForViewController(toViewController) let containerView = transitionContext.containerView() let bounds = UIScreen.mainScreen().bounds toViewController.view.frame = CGRectOffset(finalFrameForVC, 0, bounds.size.height) containerView.addSubview(toViewController.view) UIView.animateWithDuration(transitionDuration(transitionContext), delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.0, options: .CurveLinear, animations: { fromViewController.view.alpha = 0.5 toViewController.view.frame = finalFrameForVC }, completion: { finished in transitionContext.completeTransition(true) fromViewController.view.alpha = 1.0 }) } }
向ViewController.swift文件添加以下代碼。
import UIKit class ViewController: UIViewController, UIViewControllerTransitioningDelegate { // ... let customPresentAnimationController = CustomPresentAnimationController() override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { if segue.identifier == "showAction" { let toViewController = segue.destinationViewController as! UIViewController toViewController.transitioningDelegate = self } } func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { return customPresentAnimationController } }
向CustomDismissAnimationController.swift添加以下代碼。
import UIKit class CustomDismissAnimationController: NSObject, UIViewControllerAnimatedTransitioning { func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval { return 1.0 } func animateTransition(transitionContext: UIViewControllerContextTransitioning) { let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)! let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)! let finalFrameForVC = transitionContext.finalFrameForViewController(toViewController) let containerView = transitionContext.containerView() toViewController.view.frame = finalFrameForVC toViewController.view.alpha = 0.5 containerView.addSubview(toViewController.view) containerView.sendSubviewToBack(toViewController.view) UIView.animateWithDuration(transitionDuration(transitionContext), animations: { fromViewController.view.frame = CGRectInset(fromViewController.view.frame, fromViewController.view.frame.size.width / 2, fromViewController.view.frame.size.height / 2) toViewController.view.alpha = 1.0 }, completion: { finished in transitionContext.completeTransition(true) }) } }
向ViewController.swift添加以下代碼。
import UIKit class ViewController: UIViewController, UIViewControllerTransitioningDelegate { // .. // MARK: - for Segue's present modally action // ... let customDismissAnimationController = CustomDismissAnimationController() @IBAction func dimssViewController(segue: UIStoryboardSegue) { } // MARK: - UIViewControllerTransitioningDelegate's method // ... func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { return customDismissAnimationController } }
向CustomNavigationAnimationController.swift添加以下代碼。(其實是使用第三步的切換效果)
import UIKit class CustomNavigationAnimationController: NSObject, UIViewControllerAnimatedTransitioning { func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval { return 2.0 } func animateTransition(transitionContext: UIViewControllerContextTransitioning) { let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)! let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)! let finalFrameForVC = transitionContext.finalFrameForViewController(toViewController) let containerView = transitionContext.containerView() toViewController.view.frame = finalFrameForVC toViewController.view.alpha = 0.5 containerView.addSubview(toViewController.view) containerView.sendSubviewToBack(toViewController.view) UIView.animateWithDuration(transitionDuration(transitionContext), animations: { fromViewController.view.frame = CGRectInset(fromViewController.view.frame, fromViewController.view.frame.size.width / 2, fromViewController.view.frame.size.height / 2) toViewController.view.alpha = 1.0 }, completion: { finished in transitionContext.completeTransition(true) }) } }
向ViewController.swift添加以下代碼。
import UIKit class ViewController: UIViewController, UIViewControllerTransitioningDelegate, UINavigationControllerDelegate { // ... // MARK: - for Segue's present modally action // ... let customNavigationAnimationController = CustomNavigationAnimationController() // MARK: - UIViewControllerTransitioningDelegate's method // ... // MARK: - UINavigationControllerDelegate's method func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { return customNavigationAnimationController } }
注:此效果是後來添加的,因爲在設計Demo的時候沒有考慮到,因此就在Demo項目中就沒有實現。代碼來自參考的文章。
新建一個「CustomInteractionController」類。並編輯這個類文件爲以下所示。
import UIKit class CustomInteractionController: UIPercentDrivenInteractiveTransition { var navigationController: UINavigationController! var shouldCompleteTransition = false var transitionInProgress = false var completionSeed: CGFloat { return 1 - percentComplete } func attachToViewController(viewController: UIViewController) { navigationController = viewController.navigationController setupGestureRecognizer(viewController.view) } private func setupGestureRecognizer(view: UIView) { view.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: "handlePanGesture:")) } func handlePanGesture(gestureRecognizer: UIPanGestureRecognizer) { let viewTranslation = gestureRecognizer.translationInView(gestureRecognizer.view!.superview!) switch gestureRecognizer.state { case .Began: transitionInProgress = true navigationController.popViewControllerAnimated(true) case .Changed: var const = CGFloat(fminf(fmaxf(Float(viewTranslation.x / 200.0), 0.0), 1.0)) shouldCompleteTransition = const > 0.5 updateInteractiveTransition(const) case .Cancelled, .Ended: transitionInProgress = false if !shouldCompleteTransition || gestureRecognizer.state == .Cancelled { cancelInteractiveTransition() } else { finishInteractiveTransition() } default: println("Swift switch must be exhaustive, thus the default") } } }
向ViewController.swift文件添加以下代碼。
// // ViewController.swift // ViewTransition // // Created by CongJunfeng on 15/8/2. // Copyright (c) 2015年 46day. All rights reserved. // import UIKit class ViewController: UIViewController, UIViewControllerTransitioningDelegate, UINavigationControllerDelegate { // ... // MARK: - for Segue's present modally action // ... let customInteractionController = CustomInteractionController() // for Interaction // MARK: - UIViewControllerTransitioningDelegate's method // ... // MARK: - UINavigationControllerDelegate's method func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? { /** * for Interaction */ if operation == .Push { customInteractionController.attachToViewController(toVC) } return customNavigationAnimationController } // for Interaction func navigationController(navigationController: UINavigationController, interactionControllerForAnimationController animationController: UIViewControllerAnimatedTransitioning) -> UIViewControllerInteractiveTransitioning? { return customInteractionController.transitionInProgress ? customInteractionController : nil } }