iOS(视图控制器转场)
转场需要提供转场代理,不使用默认的代理则需要自己实现代理方式,有UINavigationController、UITabBarController、UIViewController三种代理,实现以下三种协议
<UINavigationControllerDelegate> //push和pop切换
<UITabBarControllerDelegate> //tab切换
<UIViewControllerTransitioningDelegate> //UICollectionViewController 与 UINavigationController 结合的转场方式
转场触发时,需要UIKit 将要求转场代理将提供转场动画的核心构件:动画控制器和交互控制器
动画控制器(Animation Controller):
最重要的部分,负责添加视图以及执行动画;遵守<UIViewControllerAnimatedTransitioning>
协议;由我们实现。
交互控制器
通过交互手段,通常是手势来驱动动画控制器实现的动画,使得用户能够控制整个过程;遵守<UIViewControllerInteractiveTransitioning>
协议;系统已经打包好现成的类供我们使用
转场环境(Transition Context):
提供转场中需要的数据;遵守<UIViewControllerContextTransitioning>
协议;由 UIKit 在转场开始前生成并提供给我们提交的动画控制 器和交互控制器使用。
转场协调器(Transition Coordinator):
可在转场动画发生的同时并行执行其他的动画,其作用与其说协调不如说辅助,主要在 Modal 转场和交互转场取消时使用,其他时候很少用到;遵守<UIViewControllerTransitionCoordinator>
协议;由 UIKit 在转场时生成,UIViewController 在 iOS 7 中新增了方法transitionCoordinator()
返回一个遵守该协议的对象,且该方法只在该控制器处于转场过程中才返回一个此类对象,不参与转场时返回 nil
动画控制器协议实现:
//返回动画时间
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
return self.duration;
}
//执行动画
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
//返回容器视图,转场发生的地方
//获取参与转场的视图控制器,有 UITransitionContextFromViewControllerKey 和 UITransitionContextToViewControllerKey 两个 Key。
//通过viewForKey:获取的视图是viewControllerForKey:返回的控制器的根视图,或者 nil。viewForKey:方法返回 nil 只有一种情况: UIModalPresentationCustom 模式下的 Modal 转场 ,通过此方法获取 presentingView 时得到的将是 nil,在后面的 Modal 转场里会详细解释。
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *toView = toVC.view;
UIView *fromView = fromVC.view;
[self animateTransition:transitionContext fromVC:fromVC toVC:toVC fromView:fromView toView:toView];
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext fromVC:(UIViewController *)fromVC toVC:(UIViewController *)toVC fromView:(UIView *)fromView toView:(UIView *)toView {
// Add the toView to the container
UIView* containerView = [transitionContext containerView];
[containerView addSubview:toView];
[containerView sendSubviewToBack:toView];
CGSize size = toView.frame.size;
NSMutableArray *snapshots = [NSMutableArray new];
CGFloat xFactor = 10.0f;
CGFloat yFactor = xFactor * size.height / size.width;
// snapshot the from view, this makes subsequent snaphots more performant
UIView *fromViewSnapshot = [fromView snapshotViewAfterScreenUpdates:NO];
// create a snapshot for each of the exploding pieces
for (CGFloat x=0; x < size.width; x+= size.width / xFactor) {
for (CGFloat y=0; y < size.height; y+= size.height / yFactor) {
CGRect snapshotRegion = CGRectMake(x, y, size.width / xFactor, size.height / yFactor);
UIView *snapshot = [fromViewSnapshot resizableSnapshotViewFromRect:snapshotRegion afterScreenUpdates:NO withCapInsets:UIEdgeInsetsZero];
snapshot.frame = snapshotRegion;
[containerView addSubview:snapshot];
[snapshots addObject:snapshot];
}
}
[containerView sendSubviewToBack:fromView];
// animate
NSTimeInterval duration = [self transitionDuration:transitionContext];
[UIView animateWithDuration:duration animations:^{
for (UIView *view in snapshots) {
CGFloat xOffset = [self randomFloatBetween:-100.0 and:100.0];
CGFloat yOffset = [self randomFloatBetween:-100.0 and:100.0];
view.frame = CGRectOffset(view.frame, xOffset, yOffset);
view.alpha = 0.0;
view.transform = CGAffineTransformScale(CGAffineTransformMakeRotation([self randomFloatBetween:-10.0 and:10.0]), 0.01, 0.01);
}
} completion:^(BOOL finished) {
for (UIView *view in snapshots) {
[view removeFromSuperview];
}
[transitionContext completeTransition:![transitionContext transitionWasCancelled]];
}];
}
- (float)randomFloatBetween:(float)smallNumber and:(float)bigNumber {
float diff = bigNumber - smallNumber;
return (((float) (arc4random() % ((unsigned)RAND_MAX + 1)) / RAND_MAX) * diff) + smallNumber;
}
参考链接:http://blog.devtang.com/2016/03/13/iOS-transition-guide/
iOS(视图控制器转场)的更多相关文章
- iOS 视图控制器转场详解
iOS 视图控制器转场详解 前言的前言 唐巧前辈在微信公众号「iOSDevTips」以及其博客上推送了我的文章后,我的 Github 各项指标有了大幅度的增长,多谢唐巧前辈的推荐.有些人问我相关的问题 ...
- 笔记-iOS 视图控制器转场详解(上)
这是一篇长文,详细讲解了视图控制器转场的方方面面,配有详细的示意图和代码,为了使得文章在微信公众号中易于阅读,seedante 辛苦将大量长篇代码用截图的方式呈现,另外作者也在 Github 上附上了 ...
- iOS 视图控制器转场动画/页面切换效果/跳转动画 学习
一 学习 在 UINavigationController 中 push 和 pop 的转场效果 (基于iOS7 以上的转场方式) 经过学习了解到,重点分三块: (1)pushAnimation: ...
- iOS 动画学习之视图控制器转场动画
一.概述 1.系统会创建一个转场相关的上下文对象,传递到动画执行器的animateTransition:和transitionDuration:方法,同样,也会传递到交互Controller的star ...
- iOS视图控制器的生命周期
今天面试有一道面试题因为回答不好,因为也不经常涉及所以有点模糊,我选择了最保守的回答,没有展开写出我对这个问题的理解. 问题:IOS 开发 loadView 和 viewDidLoad 的区别? 经过 ...
- iOS,视图控制器相关(UIViewController)
1.视图控制器各个方法调用时机 2.选项卡(Tab Bar)和导航栏(Navigation Bar) 3.有无控制器的页面跳转 4.页面跳转隐藏底部选项卡 5.获取导航栏和状态栏高度,隐藏导航栏返回按 ...
- 学习笔记:iOS 视图控制器(UIViewController)剖析
转自:http://www.cnblogs.com/martin1009/archive/2012/06/01/2531136.html 视图控制器在iOS编程中占据非常重要的位置,因此我们一定要掌握 ...
- iOS 视图控制器 (内容根据iOS编程编写)
视图控制器是 UIViewController 类或其子类对象.每个视图控制器都负责管理一个视图层次结构,包括创建视图层级结构中的视图并处理相关用户事件,以及将整个视图层次结构添加到应用窗口. 创建 ...
- iOS视图控制器初始化问题
最近在群里见不少人 问到用视图控制器的alloc /init方法初始化的时候,出来的是黑色的空界面.之前我也遇到过,所以在这里总结下. 我们在项目中肯定都会用到自定义的ViewController,而 ...
随机推荐
- CRM 2016 子表单中N:1关系 字段要求与新建时的关系
父表单在新建子表单项时弹出的窗口和 子表单的N:1关系是有关系的.说白了就是子表单窗体上的父表单字段是不是必填项. 关系如下: 1 非必填项 点击子表单的"+"号时,会出现look ...
- WORD的公式无法与文字对齐
在使用Mathtype编辑公式后,经常出现以下公式与文字无法对齐的问题: 可以使用以下方式来解决:
- SQL 会议消费记录统计
统计 /****** Object: Procedure [dbo].[JOB_UP_Summit_UserConfStat] Script Date: 2014-3-17 10:00:50 **** ...
- 【转载】Understand the serialVersionUID
If you have ever implemented Serializable interface, you must encounter this warning message The ser ...
- Mono自定义图片按钮
首先,我们编写一个MyImageButton类,继承自LinearLayout public class MyPhoneImageButton:LinearLayout { private Image ...
- Chrome和Firefox浏览器执行new Date() 函数传参数得到不同结果的陷阱
某日,同事问到关于new Date() 函数传参数,在火狐浏览器和谷歌浏览器控制台运行,会得到不同的结果,刚开始觉得不可能,后来实际操作才发现此陷阱 var date = new Date('2014 ...
- jQuery 中对 CommonJs 的支持处理
jQuery 中对 CommonJs提供了直接支持,可以在 CommonJs模块中直接引用 jQuery 对象,这是如何实现的呢? 从 factory 函数说起 说先看 jQuery 的主体函数定义, ...
- Hive修改表
Alter Table 语句 它是在Hive中用来修改的表. 语法 声明接受任意属性,我们希望在一个表中修改以下语法. ALTER TABLE name RENAME TO new_name ALTE ...
- Java堆内存的十个要点
Java中的堆空间是什么? 当Java程序开始运行时,JVM会从操作系统获取一些内存.JVM使用这些内存,这些内存的一部分就是堆内存.堆内存通常在存储地址的底层,向上排列.当一个对象通过new关键字或 ...
- cs107
基本类型:bool,char,short,int,long,float,double 对于char,short,int,long: 多字节类型赋值给少字节类型,对低字节的细节感兴趣,位模式拷贝. 少字 ...