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 } }