玩转iOS转场动画(一)

简介: 玩转iOS转场动画

一、引言


   关于动画在iOS开发中的应用,曾经整理过一系列的博客进行总结。包括简单的UIView层的动画,CALayer层的动画,Autolayout自动布局动画以及CoreAnimation核心动画框架等。本篇博客主要深入讨论视图控制器、导航控制器来进行界面跳转时的专场动画相关内容。之前的动画相关博客列举如下:


iOS动画开发之一——UIViewAnimation动画的使用:https://my.oschina.net/u/2340880/blog/484457


iOS动画开发之二——UIView动画执行的另一种方式:https://my.oschina.net/u/2340880/blog/484538


iOS动画开发之三——UIView的转场切换:https://my.oschina.net/u/2340880/blog/484669


iOS动画开发之四——核心动画编程(CoreAnimation):https://my.oschina.net/u/2340880/blog/484793


iOS动画开发之五——炫酷的粒子效果:https://my.oschina.net/u/2340880/blog/485095


iOS开发CoreAnimation解读之一——初识CoreAnimation核心动画编程:https://my.oschina.net/u/2340880/blog/535235


iOS开发CoreAnimation解读之二——对CALayer的分析:https://my.oschina.net/u/2340880/blog/536048


iOS开发CoreAnimation解读之三——几种常用Layer的使用解析:https://my.oschina.net/u/2340880/blog/538024


iOS开发CoreAnimation解读之四——Layer层动画内容:https://my.oschina.net/u/2340880/blog/539599


iOS开发CoreAnimation解读之五——高级动画技巧:https://my.oschina.net/u/2340880/blog/539827


iOS开发CoreAnimation解读之五——CATransform3D变换的应用:https://my.oschina.net/u/2340880/blog/539878


iOS中播放gif动态图的方式探讨:https://my.oschina.net/u/2340880/blog/608560


iOS界面布局之三——纯代码的autoLayout及布局动画:https://my.oschina.net/u/2340880/blog/524089


开始本篇博客前,先上一张图,如果你觉得不好理解,没关系,看完后面的内容再回来看这张图,就一目了然了。


image.png


二、UIViewController进行模态跳转的转场


   首先,使用CoreAnimation框架中的CATransition类也可以实现视图控制器的转场动画,前面的博客有过讨论,这里不再重复。presentViewController这个函数使用率可谓是非常高的,默认的转场动画为新的视图控制器从下向上弹出,dismissViewControllerAnimated函数的返回动画则是弹出动画的逆序播放。其实,系统提供了4种转场动画供开发者选择,通过设置将要弹出的UIViewController实例的如下属性:


@property(nonatomic,assign) UIModalTransitionStyle modalTransitionStyle;

UIModalTransitionStyle是一个枚举,如下:


typedef NS_ENUM(NSInteger, UIModalTransitionStyle) {

   UIModalTransitionStyleCoverVertical = 0,  //从下向上弹起  默认项

   UIModalTransitionStyleFlipHorizontal __TVOS_PROHIBITED, //水平翻转

   UIModalTransitionStyleCrossDissolve,    //渐隐渐现

   UIModalTransitionStylePartialCurl NS_ENUM_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED, //翻页

};

很多时候,上面4种枚举的转场动画样式并不能满足我们的需求,我们可以使用UIViewControllerTransitioningDelegate协议来完全自定义想要的转场动画效果。


   首先创建一个类,使其遵守UIViewControllerTransitioningDelegate协议,比如我这里将类名去做TransDelegate,继承自NSObject。在界面跳转时,将要弹出的视图控制器设置如下:


ViewController2 * v2 = [ViewController2 new];

self.transDelegate = [[TransDelegate alloc]init];

v2.transitioningDelegate = self.transDelegate;

[self presentViewController:v2 animated:YES completion:nil];

我们先来看UIViewControllerTransitioningDelegate协议中的如下几个函数:


//这个函数用来设置当执行present方法时 进行的转场动画

/*

presented为要弹出的Controller

presenting为当前的Controller

source为源Contrller 对于present动作  presenting与source是一样的

*/

- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source;

//这个函数用来设置当执行dismiss方法时 进行的转场动画

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


//这个函数用来设置当执行present方法时 进行可交互的转场动画

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

//这个函数用来设置当执行dismiss方法时 进行可交互的转场动画

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

//iOS8后提供的新接口  返回UIPresentationController处理转场

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

我们先来看上面的前两个函数,这两个函数都要返回一个实现了UIViewControllerAnimatedTransitioning协议的对象,UIViewControllerAnimatedTransitioning则用来负责具体的动画展示,例如我们在创建一个命名为AniObject的类,继承自NSObject,使其实现UIViewControllerAnimatedTransitioning协议,在TransDelegate类中实现如下:


- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{

   return [AniObject new];

}

下面我们来实现AniObject类来具体的处理动画效果:


UIViewControllerAnimatedTransitioning协议中有两个函数是必须实现的,如下:


//这个函数用来设置动画执行的时长

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

   return 2;

}

//这个函数用来处理具体的动画

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

   //跳转的界面

   UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

   //最终的位置

   CGRect finalRect = [transitionContext finalFrameForViewController:toVC];

   //起始位置

   toVC.view.frame = CGRectOffset(finalRect, [[UIScreen mainScreen]bounds].size.width, 0);

   //添加到内容视图

   [[transitionContext containerView]addSubview:toVC.view];

   //执行动画

   [UIView animateWithDuration:[self transitionDuration:transitionContext]  animations:^{

       toVC.view.frame = finalRect;

   } completion:^(BOOL finished) {

       //完成动画

       [transitionContext completeTransition:YES];

   }];

}

上面我们实现了一个简单的自定义转场动画,将present动画修改成了从右侧滑入,但是dismiss动画依然是默认的从下方划出。



下面我们来分析下transitionContext这个对象,这个对象实际上是一个转场上下文,使用它来进行动画的定义和执行:


//容器视图 用来表现动画

@property(nonatomic, readonly) UIView *containerView;

//下面是几个只读属性

//是否应该执行动画

@property(nonatomic, readonly, getter=isAnimated) BOOL animated;

//是否是可交互的

@property(nonatomic, readonly, getter=isInteractive) BOOL interactive; // This indicates whether the transition is currently interactive.

//是否被取消了

@property(nonatomic, readonly) BOOL transitionWasCancelled;

//转场风格

@property(nonatomic, readonly) UIModalPresentationStyle presentationStyle;

//调用这个函数来更新转场过程的百分比 用于可交互动画的阈值

- (void)updateInteractiveTransition:(CGFloat)percentComplete;

//完成可交互的转场交互动作时调用

- (void)finishInteractiveTransition;

//取消可交互的转场交互动作时调用

- (void)cancelInteractiveTransition;

//转场动画被中断  暂停时调用

- (void)pauseInteractiveTransition;

//转场动画完成时调用

- (void)completeTransition:(BOOL)didComplete;

//获取转场中的两个视图控制器

/*

UITransitionContextViewControllerKey的定义

UITransitionContextFromViewControllerKey  //原视图控制器

UITransitionContextToViewControllerKey    //跳转的视图控制器

*/

- (nullable __kindof UIViewController *)viewControllerForKey:(UITransitionContextViewControllerKey)key;

//直接获取转场中的视图

/*

UITransitionContextFromViewKey  //原视图

UITransitionContextToViewKey    //转场的视图

*/

- (nullable __kindof UIView *)viewForKey:(UITransitionContextViewKey)key;

//获取视图控制器的初识位置

- (CGRect)initialFrameForViewController:(UIViewController *)vc;

//获取视图控制器转场后的位置

- (CGRect)finalFrameForViewController:(UIViewController *)vc;

通过上面的介绍,我们可以使用UIViewControllerContextTransitioning随心所欲的定制转场动画,但是还有一个困难我们无法克服,那就是可以交互的转场动画。我们在使用系统的导航控制器时,右划返回效果对用户体验十分友好,我们下面就来试着将视图控制器的模态跳转设计成类似导航可交互的。




目录
相关文章
|
iOS开发
iOS 动画绘制圆形
iOS 动画绘制圆形
82 1
|
编译器 iOS开发 异构计算
读iOS核心动画笔记
读iOS核心动画笔记
55 0
|
24天前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户点击按钮时,按钮将从圆形变为椭圆形,颜色从蓝色渐变到绿色;释放按钮时,动画以相反方式恢复。通过UIView的动画方法和弹簧动画效果,实现平滑自然的过渡。
45 1
|
1月前
|
Swift iOS开发 UED
如何使用Swift和UIKit在iOS应用中实现自定义按钮动画
【10月更文挑战第18天】本文通过一个具体案例,介绍如何使用Swift和UIKit在iOS应用中实现自定义按钮动画。当用户按下按钮时,按钮将从圆形变为椭圆形并从蓝色渐变为绿色;释放按钮时,动画恢复原状。通过UIView的动画方法和弹簧动画效果,实现平滑自然的动画过渡。
50 5
|
2月前
|
Swift iOS开发 UED
揭秘一款iOS应用中令人惊叹的自定义动画效果,带你领略编程艺术的魅力所在!
【9月更文挑战第5天】本文通过具体案例介绍如何在iOS应用中使用Swift与UIKit实现自定义按钮动画,当用户点击按钮时,按钮将从圆形变为椭圆形并从蓝色渐变到绿色,释放后恢复原状。文中详细展示了代码实现过程及动画平滑过渡的技巧,帮助读者提升应用的视觉体验与特色。
63 11
|
3月前
|
Swift iOS开发 UED
【绝妙创意】颠覆你的视觉体验!揭秘一款iOS应用中令人惊叹的自定义动画效果,带你领略编程艺术的魅力所在!
【8月更文挑战第13天】本文通过一个具体案例,介绍如何使用Swift与UIKit在iOS应用中创建独特的按钮动画效果。当按钮被按下时,其形状从圆形变化为椭圆形,颜色则从蓝色渐变为绿色;释放后,动画反向恢复原状。利用UIView动画方法及弹簧动画效果,实现了平滑自然的过渡。通过调整参数,开发者可以进一步优化动画体验,增强应用的互动性和视觉吸引力。
52 7
|
iOS开发
iOS 常用阅读软件打开书籍的转场动画
iOS 常用阅读软件打开书籍的转场动画
94 0
|
6月前
|
iOS开发
iOS设备功能和框架: 如何使用 Core Animation 创建动画效果?
iOS设备功能和框架: 如何使用 Core Animation 创建动画效果?
137 0
|
API iOS开发
iOS 自定义转场动画 UIViewControllerTransitioning
iOS 自定义转场动画 UIViewControllerTransitioning
96 0
|
iOS开发
iOS - 个人中心果冻弹性下拉动画
iOS - 个人中心果冻弹性下拉动画
262 0
iOS - 个人中心果冻弹性下拉动画