美文网首页
在swift中实现自定义转场动画

在swift中实现自定义转场动画

作者: b002cf285d26 | 来源:发表于2016-07-08 22:56 被阅读218次

    1.需求确认

          在HomeViewController中, 点击TitleButton, 通过自定义转场动画的方式modal出一小块的PopoverViewController

    2.类索引

          1) HomeViewController : BaseViewController
    -- "源控制器", 负责发起自定义转场
          2) PopoverViewController : UIViewController
    -- "目标控制器", 通过自定义转场而被展现
          3) PopoverPresentationController : UIPresentationController
    -- "转场控制器", 负责配置自身容器属性, 将目标控制器的view添加到容器中, 容器本质也是一个view
          4) PopoverAnimator : NSObject
    -- 自定义转场动画类, 用于将下面两个代理中的方法从源控制器中进行抽离, 使源控制器只保留逻辑代码, 保证其代码的整洁和优雅
          5) UIViewControllerTransitioningDelegate
     -- 常用三个代理方法, 用于告诉系统谁是转场控制器, 谁负责转场动画的开始, 谁负责转场动画的结束
          6) UIViewControllerAnimatedTransitioning
    -- 常用两个代理方法, 用于告诉系统转场动画的持续时间与实现

    3.实现步骤


    1) 设置目标控制器的代理对象

    popoverViewController.transitioningDelegate = 自定义转场动画类的实例化对象

    2) 设置目标控制器的转场样式

    popoverViewController.modalPresentationStyle= UIModalPresentationStyle.Custom

    3) 自定义转场控制器类 PopoverPresentationController : UIPresentationController
    在这个类中, 着重使用了两个属性, 并重写两个方法:

    containerView : 容器属性, 所有被展现的东西都在这个view内部
    presentedView() : 返回目标控制器的view

    init(presentedViewController, presentingViewController)
    初始化方法, 记得调用'super.'对父类初始化
    第一个参数: 目标控制器
    第二个参数: 在Xcode6为nil, Xcode7为野指针

    containerViewWillLayoutSubviews()
    容器布局方法, 该方法会在转场前进行调用, 对容器内的视图进行统一配置(包括: 目标控制器的view.frame、coverView等)

    4) 实现UIViewControllerTransitioningDelegate的最主要代理方法

    presentationControllerForPresentedViewController(presented,presenting, source)
    -> UIPresentationController?
    该代理方法告诉系统, 谁是转场控制器
    参数一: 目标控制器
    参数二: 在Xcode6为nil, Xcode7为野指针
    参数三: 源控制器
    返回值: 转场控制器

    5) 实现UIViewControllerTransitioningDelegate的另外两个代理方法

    animationControllerForPresentedController(presented, presenting, source)
    -> UIViewControllerAnimatedTransitioning?
    该代理方法告诉系统, 谁负责转场动画的展现, 在展现开始前被调用
    返回值: 签订UIViewControllerAnimatedTransitioning协议的对象, 这里返回转场动画类

    animationControllerForDismissedController(dismissed)
    -> UIViewControllerAnimatedTransitioning?
    该代理方法告诉系统, 谁负责转场动画的消失, 在消失开始前被调用
    返回值: 签订UIViewControllerAnimatedTransitioning协议的对象, 这里返回转场动画类

    6) 实现UIViewControllerAnimatedTransitioning的两个代理方法

    transitionDuration(transitionContext) ->NSTimeInterval
    该代理方法告诉系统, 转场动画的执行时间

    animateTransition(transitionContext)
    在该代理方法中完成动画的实现, 无论展现还是消失,都会调用这个方法
    参数: transitionContext, 里面包含了动画需要的所有参数!
    通过 transitionContext.viewControllerForKey(key) 获取目标控制器和源控制器
    通过 transitionContext.viewForKey(key) 获取展现的view和消失的view
    通过 transitionContext.containerView 获取转场控制器的容器属性
    通过 transitionDuration(transitionContext) 设置动画持续时间
    通过 transitionContext.completeTransition(true), 动画完成时告诉系统, 该步必须有!

    7) 一切准备就绪, 调用modal方法吧

    presentViewController(homeVC, animated:true, completion:nil)

    4.注意事项


    1) 自定义转场需要iOS8以上版本 

    2) 默认转场会将源控制器的view替换成目标控制器的view, 而自定义转场,不会移除源控制器的view

    3) 重写步骤5和6里面的代理方法后, 系统自带的转场动画(从下至上)就已经没有了

    4) 在代理方法animateTransition(transitionContext)中, 通过使用transitionContext.viewForKey(key)获取到要展现的视图后,一定要将其添加到容器中, 否则弹窗弹不出来!

    5) 在转场动画完成后, 一定要调用transitionContext.completeTransition(true), 否则会产生各种未知的问题(如同在layoutSubviews()中不调用super一样)

    6) 在UIView.animateWithDuration()中, 如果调用了CGAffineTransformMakeScale等参数类型为CGFloat的方法, 填0.0会没有动画, 由于系统缺陷导致CGFloat类型是不准确的.

    相关文章

      网友评论

          本文标题:在swift中实现自定义转场动画

          本文链接:https://www.haomeiwen.com/subject/exerjttx.html