UIPresentationController自定义转场动画
2016-04-01 10:54
369 查看
在APP开发过程中,总要设计到控制器的跳转。在IOS8中,苹果推出了UIPresentationController来管理所有modal的控制器。在这里,我们首选回顾一下,系统自带的modal转场动画效果。modalTransitionStyle分别有已下四种效果:
这个在使用的过程中,仅仅需要修改需要切换控制器的modalTransitionStyle分隔即可。
例如,单击主控制器的跳转到下一个控制器的实现
而到了IOS8以后,苹果推出UIPresentationController可以实现自定义的控制器切换效果,下面我们具体的来学习使用一下。
我们采用一个小demo示例来对其进行演示,首次采用了自动布局的来搭建界面。如下图所示:
其中前四个转场效果为苹果系统自带的,如前面讲到的只需要修改modalTransitionStyle的值即可。最后一个效果是自定义转场实现出来的效果,下面我们来进行具体的阐述
在单击了“自定义左右效果”按钮后,需要设置其 设置展示样式为自定义样式
除此之外,还需要三个对象来实现自定义过渡,一个UIPresentationController 的子类、一个遵从 UIViewControllerAnimatedTransitioning 协议的类以及遵从UIViewControllerTransitioningDelegate协议的类。
具体代码为:
需要自定义转场动画后,需要实现要调整控制器的transitioningDelegate代理。创建实现UIViewControllerTransitioningDelegate协议的类(这里我们命名为Transition (并且将其设置成为单例)),在这个类中实现UIViewControllerTransitioningDelegate协议方法
详细信息可以点此查看完整代码
下面首先实现一个 UIPresentationController 的子类(PresentationController)
详细信息可以点此查看完整代码
最后实现一个遵守UIViewControllerAnimatedTransitioning 协议的类(AnimatedTransitioning)
实现方法
详细信息点此查看完整代码
这样只需要
这个方法中修改完成相应的转场动画。
最后对上述步骤进行总结归纳:
第一步:创建需要modal的控制器
第二步: 设置展示样式(自定义)
第三步:成为其transitioningDelegate的代理
第四步:modal控制器
第五步:实现Transition(单例)类(一个实现了UIViewControllerTransitioningDelegate协议的类)
并实现代理方法
第六步:根据第五步的代理方法创建一个继承自UIPresentationController 的自定义类,并在其中实现方法下述方法
第七步:根据第五步的代理方法创建一个实现UIViewControllerAnimatedTransitioning协议的类,并在其中实现下述方法,设置转场动画效果。
按照相应逻辑实现,即可完成自定义转场动画。
最后:一个上述方法实现的小demo已经上传到github上,可以单击此处下载
/* UIModalTransitionStyleCoverVertical 默认效果:自下而上 UIModalTransitionStyleFlipHorizontal 翻转效果 UIModalTransitionStyleCrossDissolve 淡出效果 UIModalTransitionStylePartialCurl 上下翻页效果 */
这个在使用的过程中,仅仅需要修改需要切换控制器的modalTransitionStyle分隔即可。
例如,单击主控制器的跳转到下一个控制器的实现
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { //初始化要切换的控制器 UIViewController *vc = [[UIViewController alloc] init]; //设置其背景颜色 vc.view.backgroundColor = [UIColor redColor]; // 设置动画样式(系统自带的调整方式四种) vc.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; //控制器跳转 [self presentViewController:vc animated:YES completion:nil]; }
而到了IOS8以后,苹果推出UIPresentationController可以实现自定义的控制器切换效果,下面我们具体的来学习使用一下。
我们采用一个小demo示例来对其进行演示,首次采用了自动布局的来搭建界面。如下图所示:
其中前四个转场效果为苹果系统自带的,如前面讲到的只需要修改modalTransitionStyle的值即可。最后一个效果是自定义转场实现出来的效果,下面我们来进行具体的阐述
在单击了“自定义左右效果”按钮后,需要设置其 设置展示样式为自定义样式
vc.modalPresentationStyle = UIModalPresentationCustom;
除此之外,还需要三个对象来实现自定义过渡,一个UIPresentationController 的子类、一个遵从 UIViewControllerAnimatedTransitioning 协议的类以及遵从UIViewControllerTransitioningDelegate协议的类。
具体代码为:
//在ViewController中点击事件实现: //要切换的控制器 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { //初始化要切换的控制器 UIViewController *vc = [[UIViewController alloc] init]; //设置其背景颜色 vc.view.backgroundColor = [UIColor redColor]; //设置展示样式(自定义) vc.modalPresentationStyle = UIModalPresentationCustom; //设置代理(设置UIPresentationController)(为实现UIViewControllerTransitioningDelegate协议的类) vc.transitioningDelegate = [Transition sharedtransition]; //控制器跳转 [self presentViewController:vc animated:YES completion:nil]; }
需要自定义转场动画后,需要实现要调整控制器的transitioningDelegate代理。创建实现UIViewControllerTransitioningDelegate协议的类(这里我们命名为Transition (并且将其设置成为单例)),在这个类中实现UIViewControllerTransitioningDelegate协议方法
#pragma mark - UIViewControllerTransitioningDelegate //设置继承自UIPresentationController 的自定义类的属性 - (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source { //return 一个UIPresentationController 的子类; return [[PresentationController alloc] initWithPresentedViewController:presented presentingViewController:presenting]; } //控制器创建执行的动画(返回一个实现UIViewControllerAnimatedTransitioning协议的类) - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { //return 一个 UIViewControllerAnimatedTransitioning 协议的类; //创建实现UIViewControllerAnimatedTransitioning协议的类(命名为AnimatedTransitioning) AnimatedTransitioning *anim = [[AnimatedTransitioning alloc] init]; //将其状态改为出现 anim.presented = YES; return anim; } //控制器销毁执行的动画(返回一个实现UIViewControllerAnimatedTransitioning协议的类) - (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed { //return 一个 UIViewControllerAnimatedTransitioning 协议的类; //创建实现UIViewControllerAnimatedTransitioning协议的类(命名为AnimatedTransitioning) AnimatedTransitioning *anim = [[AnimatedTransitioning alloc] init]; //将其状态改为出现 anim.presented = NO; return anim; }
详细信息可以点此查看完整代码
下面首先实现一个 UIPresentationController 的子类(PresentationController)
//即将出现调用 - (void)presentationTransitionWillBegin{ //添加半透明背景 View 到视图中 UIView *transtioningView = [[UIView alloc] init]; transtioningView.backgroundColor = [UIColor colorWithRed:1.0 green:0.0 blue:1.0 alpha:0.5]; self.transtioningView = transtioningView; self.transtioningView.frame = self.containerView.bounds; self.transtioningView.alpha = 0.0; [self.containerView addSubview:self.transtioningView]; //一旦要自定义动画,必须自己手动添加控制器 //设置尺寸(在动画中注意调整尺寸) self.presentedView.frame = CGRectInset(self.containerView.bounds, 40, 60); // 添加到containerView 上 [self.containerView addSubview:self.presentedView]; // 与过渡效果一起执行背景 View 的淡入效果 [[self.presentingViewController transitionCoordinator] animateAlongsideTransitionInView:self.transtioningView animation:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) { self.transtioningView.alpha = 1.0; } completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) { }]; } //出现调用 - (void)presentationTransitionDidEnd:(BOOL)completed{ // 如果呈现没有完成,那就移除背景 View if (!completed){ [self.transtioningView removeFromSuperview]; } } //即将销毁调用 - (void)dismissalTransitionWillBegin{ // 与过渡效果一起执行背景 View 的淡入效果 [[self.presentingViewController transitionCoordinator] animateAlongsideTransitionInView:self.transtioningView animation:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) { self.transtioningView.alpha = 0.0; } completion:^(id<UIViewControllerTransitionCoordinatorContext> _Nonnull context) { }]; } //销毁调用 - (void)dismissalTransitionDidEnd:(BOOL)completed{ if (completed) { //一旦要自定义动画,必须自己手动移除控制器 [self.presentedView removeFromSuperview]; [self.transtioningView removeFromSuperview]; }
详细信息可以点此查看完整代码
最后实现一个遵守UIViewControllerAnimatedTransitioning 协议的类(AnimatedTransitioning)
实现方法
#pragma mark - UIViewControllerAnimatedTransitioning - (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext{ //动画执行时间 return duration; } //实际动画效果(以后需要改的地方只有这里) - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{ if (self.presented) {//创建控制器 UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey]; //toView.layer.transform = CATransform3DMakeRotation(M_PI_2, 1, 1, 1);3D动画 //toView.y = -toView.height; toView.x = toView.width; [UIView animateWithDuration:duration animations:^{ //toView.layer.transform = CATransform3DIdentity;3D动画 //toView.y = 0; toView.x = 40;//注意同PresentationController设置的尺寸位置相关 } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; }else{//销毁控制器 [UIView animateWithDuration:duration animations:^{ UIView *fromView = [transitionContext viewForKey:UITransitionContextFromViewKey]; //fromView.layer.transform = CATransform3DMakeRotation(M_PI_2, 1, 1, 1); //fromView.y = -fromView.height; fromView.x = -fromView.width; } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; } }
详细信息点此查看完整代码
这样只需要
- (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext;
这个方法中修改完成相应的转场动画。
最后对上述步骤进行总结归纳:
第一步:创建需要modal的控制器
UIViewController *vc = [[UIViewController alloc] init];
第二步: 设置展示样式(自定义)
vc.modalPresentationStyle = UIModalPresentationCustom;
第三步:成为其transitioningDelegate的代理
//Transition(单例)为一个实现UIViewControllerTransitioningDelegate协议的类 vc.transitioningDelegate = [Transition sharedtransition];
第四步:modal控制器
[self presentViewController:vc animated:YES completion:nil];
第五步:实现Transition(单例)类(一个实现了UIViewControllerTransitioningDelegate协议的类)
并实现代理方法
#pragma mark - UIViewControllerTransitioningDelegate //设置继承自UIPresentationController 的自定义类的属性 - (UIPresentationController *)presentationControllerForPresentedViewController:(UIViewController *)presented presentingViewController:(UIViewController *)presenting sourceViewController:(UIViewController *)source; //控制器创建执行的动画(返回一个实现UIViewControllerAnimatedTransitioning协议的类) - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source; 控制器销毁执行的动画(返回一个实现UIViewControllerAnimatedTransitioning协议的类) - (id <UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed;
第六步:根据第五步的代理方法创建一个继承自UIPresentationController 的自定义类,并在其中实现方法下述方法
//即将出现调用 - (void)presentationTransitionWillBegin; //出现调用 - (void)presentationTransitionDidEnd:(BOOL)completed; //即将销毁调用 - (void)dismissalTransitionWillBegin; //销毁调用 - (void)dismissalTransitionDidEnd:(BOOL)completed;
第七步:根据第五步的代理方法创建一个实现UIViewControllerAnimatedTransitioning协议的类,并在其中实现下述方法,设置转场动画效果。
//常量,动画执行的时间 const CGFloat duration = 1.0; #pragma mark - UIViewControllerAnimatedTransitioning //动画执行的时间 - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext; //实际动画效果(以后需要改的地方只有这里) - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext;
按照相应逻辑实现,即可完成自定义转场动画。
最后:一个上述方法实现的小demo已经上传到github上,可以单击此处下载
相关文章推荐
- javaweb项目中对于资源文件的读取(to be continue)
- RValue forward sample code
- easyUI单元格合并自定义封装
- Android总结 - System UI Mode
- 【技巧】UITableView 在UITableViewStylePlain模型下,取消headerView的黏结性,不浮动
- FMDatabaseQueue 数据库多线程操作、事务处理
- 完美解决 向UILable 文字最后插入N张图片,支持向限制行数的UILable 最后一行插入,多余文字显示...
- iOS UITextView
- GreenHandX1h 4.1 questions
- uicollectionview的使用
- iOS边练边学--UIGestureRecognizer手势识别器简单介绍
- 《iOS Human Interface Guidelines》——Stepper
- UsageStatsManager.queryUsageStats的参数interval
- lintcode: N-Queens
- iOS-将UIImage转为NSData
- mysql Handler_read_rnd_next value 值超大(10G+)的处理
- 关于tableview中cell的一些加载
- UVa-1252 Twenty Questions (位运算)
- Android带虚拟按键的手机不认res/values的屏幕适配解决方案
- SearchRequestBuilder常用方法说明