美文网首页
iOS 转场动画初步

iOS 转场动画初步

作者: 翻滚的炒勺2013 | 来源:发表于2018-12-05 18:39 被阅读56次
景甜.jpg

关于转场动画

转场动画一直是一个心结,现在有时间正好把之前所学的整理下来防止自己忘记

API

在iOS5.6以前采用block的方式实现转场但是代码耦合不易于扩展和维护,针对这个问题
在iOS7之后苹果加入了新的API用于转场动画

相关知识点

548467-900501947b5d62bd.jpg

转场过程
下面是一个present动画的步骤:
1.不管是用代码还是通过segue,我们需要触发转场。
2.UIKit向"to" view controller(将被显示的view controller)的transitioning delegate询问,如果没有代理,就会用内置的默认转场动画。
3.UIKit之后向transigioning delegate通过代理方法animationControllerForPresentedController(:presentingController:sourceController:)询问一个animation controller,如果返回nil,仍然会用默认的动画。
4.一旦有一个有效的animation controller后,UIKit就会构建transitioning context。
5.UIKit之后向animation controller通过transitionDuration(
:)询问动画持续时长。
6.UIKit调用animateTransition来实现animation controller的转场动画。
7.最后animation controller调用context的completeTransition方法来表示这次动画已经结束

  • 转场协议: UIViewControllerTransitioningDelegate
    每个view controller都可以有一个transitioningDelegate代理,它实现了UIViewControllerTransitioningDelegate的协议。
    不管你是present还是dismiss一个view controller,UIKit总会向transitioning delegate询问是否有代理可用。设置view controller的transitioningDelegate为我们自定义的类来作出自定义的转场动画。
- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{
}

/*
不管是 present 还是dismiss
要是调用interactionControllerForPresentation 或者是 interactionControllerForDismissal
返回值是nil,就会走下面animationControllerForPresentedController和animationControllerForDismissedController方法
要是不是nil,就不会走下面这两个方法了, 在我们这里也就是用手势测试的时候是不会走的,点击present或 者是dismiss会走
*/
// 这个方法返回一个遵守 <UIViewControllerAnimatedTransitioning> 协议的对象
// 其实返回的就是PresentedController控制器的动画


- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed{

}

这个方法和上面的解释是类似的,只不过这里的控制器就是DismissedController


- (nullable id <UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id <UIViewControllerAnimatedTransitioning>)animator{};

UIKit还会调用代理的interactionControllerForPresentation:方法来获取交互式控制器,如果得到了nil则执行非交互式动画
// 如果获取到了不是nil的对象,那么UIKit不会调用animator的animateTransition方法,而是调用交互式控制器的startInteractiveTransition:方法。


- (nullable id <UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id <UIViewControllerAnimatedTransitioning>)animator{};

这个方法是在dismiss的时候的时候调用,也是交互转场执行的时候


- (nullable UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(nullable UIViewController *)presenting sourceViewController:(UIViewController *)source NS_AVAILABLE_IOS(8_0){};

这个方法的返回值是UIPresentationController


  • 动画协议
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
}

动画执行的时间


- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
}
  • initialFrameForViewController 开始 ViewController 的frame
    finalFrameForViewController 结束ViewController 的 frame。

  • 交互控制器协议UIViewControllerInteractiveTransitioning 简单的来说就是利用手势来完成转场

  • 动画

  • 视图


问题

两者的区别:
UIModalPresentationFullScreen
UIModalPresentationCustom

modalTransitionStyle
modalPresentationStyle

  1. modalTransitionStyle
   // 默认的从下到上
   UIModalTransitionStyleCoverVertical = 0,
   // 翻转
   UIModalTransitionStyleFlipHorizontal__TVOS_PROHIBITED,
   // 渐显
  UIModalTransitionStyleCrossDissolve,
  // 类似你翻书时候的效果
  UIModalTransitionStylePartialCurl NS_ENUM_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED,

  1. modalPresentationStyle
  //presented控制器充满全屏,如果弹出VC的wantsFullScreenLayout设置为YES的,则会填充到状态栏下边,否则不会填充到状态栏之下.iPhone默认是这个
  UIModalPresentationFullScreen = 0,
  //presented控制器的高度和当前屏幕高度相同,宽度和竖屏模式下屏幕宽度相同,剩余未覆盖区域将会变暗并阻止用户点击,这种弹出模式下,竖屏时跟UIModalPresentationFullScreen的效果一样,横屏时候两边则会留下变暗的区域
  UIModalPresentationPageSheet NS_ENUM_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED,
  //presented控制器的高度和宽度均会小于屏幕尺寸,presented VC居中显示,四周留下变暗区域。
  UIModalPresentationFormSheet NS_ENUM_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED,
  //presented控制器的弹出方式和presenting VC的父VC的方式相同。
  UIModalPresentationCurrentContext NS_ENUM_AVAILABLE_IOS(3_2),
   //自定义
   UIModalPresentationCustom NS_ENUM_AVAILABLE_IOS(7_0),
  UIModalPresentationOverFullScreen NS_ENUM_AVAILABLE_IOS(8_0),       
  UIModalPresentationOverCurrentContext NS_ENUM_AVAILABLE_IOS(8_0),
   // http://www.15yan.com/story/jlkJnPmVGzc/ 在iPad上弹出控制器
   UIModalPresentationPopover NS_ENUM_AVAILABLE_IOS(8_0) __TVOS_PROHIBITED,
   // None
   UIModalPresentationNone NS_ENUM_AVAILABLE_IOS(7_0) = -1,  


利用转场动画实现实现一个淡入淡出的效果

. 创建两个控制器分别命名为GHCrossFromViewController 和 GHCrossToViewController
. 创建一个转场动画管理类,集成自NSObject 命名为GHCrossAnimation
. GHCrossAnimation遵守动画协议,包含#import <UIKit/UIKit.h>框架
<UIViewControllerAnimatedTransitioning>
. 实现动画协议里的两个方法

- (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext;

- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext;

第一个代理方法直接返回一个时间,这个时间为动画的执行时间.
第二个代理方法主要在这个方法里实现转场动画.
伪代码:

1.获取到源控制器在这里定义为fromVc,获取到目标控制器toVc
2.获取到源控制器的view这里定义为fromView.获取到目标控制器toView
3.获取到源控制器的初始位置fromView.frame,获取到目标控制器的结束位置toView.frame
4.获取到contentView

相关文章

网友评论

      本文标题:iOS 转场动画初步

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