iOS 7 present/dismiss自定义转场动画
2015-12-21 16:21
597 查看
前言
iOS 7以后提供了自定义转场动画的功能,我们可以通过遵守协议完成自定义转场动画。本篇文章讲解如何实现自定义
present、
dismiss自定义动画。
关于自定义
push/pop转场动画,请阅读iOS 7 push/pop自定义转场动画
效果图
本篇文章实现的动画切换效果图如下:视图切换种类
如下效果图,这是有两大类视图切换动画的,一种是交互式的,另一种就是自定义的。本篇只讲其中的
UIViewControllerAnimatedTransitioning协议,来实现
present、
dismiss动画效果。另外的几个,后面会继续学习总结!!!
协议
我们要实现present、
dismiss自定义转场效果,我们必须要有一个遵守了
UIViewControllerAnimatedTransitioning协议且实现其必须实现的代理方法的类。
我们先来学习
UIViewControllerAnimatedTransitioning协议:
@protocol UIViewControllerAnimatedTransitioning <NSObject> // This is used for percent driven interactive transitions, as well as for container controllers that have companion animations that might need to // synchronize with the main animation. // // 指定转场动画时长,必须实现,否则会Crash。 // 这个方法是为百分比驱动的交互转场和有对比动画效果的容器类控制器而定制的。 - (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext; // This method can only be a nop if the transition is interactive and not a percentDriven interactive transition. // 若非百分比驱动的交互过渡效果,这个方法只能为空 - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext; @optional // This is a convenience and if implemented will be invoked by the system when the transition context's completeTransition: method is invoked. - (void)animationEnded:(BOOL) transitionCompleted; @end
我们要实现目标效果,就需要一个定义一个类遵守
UIViewControllerAnimatedTransitioning协议并实现相应的代理方法。
遵守UIViewControllerAnimatedTransitioning协议
下面,我们来定义一个转场类,这个类必须要遵守UIViewControllerAnimatedTransitioning协议,如下:
头文件
// // HYBModalTransition.h // PresentDismissTransitionDemo // // Created by huangyibiao on 15/12/21. // Copyright © 2015年 huangyibiao. All rights reserved. // #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> typedef NS_ENUM(NSUInteger, HYBModalTransitionType) { kHYBModalTransitionPresent = 1 << 1, kHYBModalTransitionDismiss = 1 << 2 }; @interface HYBModalTransition : NSObject <UIViewControllerAnimatedTransitioning> /*! * @author 黄仪标, 15-12-21 11:12:44 * * 指定动画类型 * * @param type 动画类型 * @param duration 动画时长 * @param presentHeight 弹出呈现的高度 * @param scale fromVC的绽放系数 * * @return */ + (HYBModalTransition *)transitionWithType:(HYBModalTransitionType)type duration:(NSTimeInterval)duration presentHeight:(CGFloat)presentHeight scale:(CGPoint)scale; @end
我们只公开了一个方法来创建,指定动画类型,动画时长,呈现的高度,缩放系数。
实现文件
// // HYBModalTransition.m // PresentDismissTransitionDemo // // Created by huangyibiao on 15/12/21. // Copyright © 2015年 huangyibiao. All rights reserved. // #import "HYBModalTransition.h" @interface HYBModalTransition () @property (nonatomic, assign) HYBModalTransitionType type; @property (nonatomic, assign) CGFloat presentHeight; @property (nonatomic, assign) CGPoint scale; @property (nonatomic, assign) NSTimeInterval duration; @end @implementation HYBModalTransition + (HYBModalTransition *)transitionWithType:(HYBModalTransitionType)type duration:(NSTimeInterval)duration presentHeight:(CGFloat)presentHeight scale:(CGPoint)scale { HYBModalTransition *transition = [[HYBModalTransition alloc] init]; transition.type = type; transition.presentHeight = presentHeight; transition.scale = scale; transition.duration = duration; return transition; } #pragma mark - UIViewControllerAnimatedTransitioning - (void)animationEnded:(BOOL)transitionCompleted { NSLog(@"%s", __FUNCTION__); } - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext { return self.duration; } - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext { switch (self.type) { case kHYBModalTransitionPresent: { [self present:transitionContext]; break; } case kHYBModalTransitionDismiss: { [self dismiss:transitionContext]; break; } default: { break; } } } #pragma mark - Private - (void)present:(id<UIViewControllerContextTransitioning>)transitonContext { UIViewController *fromVC = [transitonContext viewControllerForKey:UITransitionContextFromViewControllerKey]; UIViewController *toVC = [transitonContext viewControllerForKey:UITransitionContextToViewControllerKey]; UIView *containerView = [transitonContext containerView]; // 对fromVC.view的截图添加动画效果 UIView *tempView = [fromVC.view snapshotViewAfterScreenUpdates:NO]; tempView.frame = fromVC.view.frame; // 对截图添加动画,则fromVC可以隐藏 fromVC.view.hidden = YES; // 要实现转场,必须加入到containerView中 [containerView addSubview:tempView]; [containerView addSubview:toVC.view]; // 我们要设置外部所传参数 // 设置呈现的高度 toVC.view.frame = CGRectMake(0, containerView.frame.size.height, containerView.frame.size.width, self.presentHeight); // 开始动画 __weak __typeof(self) weakSelf = self; [UIView animateWithDuration:self.duration delay:0.0 usingSpringWithDamping:0.5 initialSpringVelocity:1.0 / 0.5 options:0 animations:^{ // 在Y方向移动指定的高度 toVC.view.transform = CGAffineTransformMakeTranslation(0, -weakSelf.presentHeight); // 让截图缩放 tempView.transform = CGAffineTransformMakeScale(weakSelf.scale.x, weakSelf.scale.y); } completion:^(BOOL finished) { if (finished) { [transitonContext completeTransition:YES]; } }]; } - (void)dismiss:(id<UIViewControllerContextTransitioning>)transitonContext { UIViewController *fromVC = [transitonContext viewControllerForKey:UITransitionContextFromViewControllerKey]; UIViewController *toVC = [transitonContext viewControllerForKey:UITransitionContextToViewControllerKey]; UIView *containerView = [transitonContext containerView]; // 取出present时的截图用于动画 UIView *tempView = containerView.subviews.lastObject; // 开始动画 [UIView animateWithDuration:self.duration animations:^{ toVC.view.transform = CGAffineTransformIdentity; fromVC.view.transform = CGAffineTransformIdentity; } completion:^(BOOL finished) { if (finished) { [transitonContext completeTransition:YES]; toVC.view.hidden = NO; // 将截图去掉 [tempView removeFromSuperview]; } }]; } @end
我们这里就不细讲了,因为在iOS 7 push/pop自定义转场动画中已经讲过了。大家若未看过,可以先阅读。
测试效果
我们要设置一下被present的控制器的代理,在
-viewDidLoad:时添加如下代码:
// 配置一下代理防呈现样式为自定义 self.transitioningDelegate = self; self.modalPresentationStyle = UIModalPresentationCustom;
同时,还需要遵守协议并实现协议
UIViewControllerTransitioningDelegate,这个是控制器转场动画实现的代理:
#pragma mark - UIViewControllerTransitioningDelegate - (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { return [HYBModalTransition transitionWithType:kHYBModalTransitionPresent duration:0.5 presentHeight:350 scale:CGPointMake(0.9, 0.9)]; } - (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed { return [HYBModalTransition transitionWithType:kHYBModalTransitionDismiss duration:0.25 presentHeight:350 scale:CGPointMake(0.9, 0.9)]; }
我们设置
present、
dismiss自定义对象,就可以实现我们的动画了。
想要实现什么样的动画,都可以在
HYBModalTransition类里面实现,没有实现不了,只有想不到!!!
写在最后
初步研究这方面的知识,最近要做技术分享,正好也好好研究研究,如果写得不好,希望大家不要笑话!!!其它转场效果,后续会分享出来!!!
其它转场效果,后续会分享出来!!!
其它转场效果,后续会分享出来!!!
源代码
小伙伴们可以到笔者的github下载:https://github.com/CoderJackyHuang/ModalTransitionDemo
请随手给一个star吧!!!
阅读原文
关注我
微信公众号:iOSDevShares有问必答QQ群:324400294
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- Gifski:一个跨平台的高质量 GIF 编码器
- 模仿动画的放大缩小容器
- jQuery 1.9.1源码分析系列(十五)动画处理之缓动动画核心Tween
- Android中ViewFlipper的使用及设置动画效果实例详解
- jQuery实现美观的多级动画效果菜单代码
- php判断GIF图片是否为动画的方法
- jQuery实现动画效果circle实例
- 浅析JavaScript动画
- js排序动画模拟-插入排序
- javascript+HTML5的Canvas实现Lab单车动画效果
- 基于javascript实现漂亮的页面过渡动画效果附源码下载
- js实现按钮颜色渐变动画效果
- jQuery实现连续动画效果实例分析