基本概念
- animation controller:
- 包含运行实际动画的代码
- 代理
<UIViewControllerAnimatedTransitioning>
- -transitionDuration: 动画时间
- -animateTransition: 具体动画实现
- from view Controller:
- 提供自定义转场动画animation controller
- 代理
<UIViewControllerTransitioningDelegate>
- -(id)animationControllerForPresentedController: presentingController: sourceController:
- to view Controller:
- toVC.transitioningDelegate = fromVC
- transitionContext:
- 获取to/from VCs,animation controller,containing UIView
创建一个定制的转场动画需要三步:
- 创建animation controller
创建一个animation controller的类,该类实现<UIViewControllerAnimatedTransitioning>
protocol,该类中包含了运行实际动画的代码。 - 在即将转换显示一个view controller之前,先设置它的代理。
该代理通常是当前显示的view controller,当转场到下一个view controller时,代理会收到一个获取animation controller的回调。 - 在回调是返回animation controller
1. 创建animation controller:
@interface BouncePresentAnimationController : NSObject <UIViewControllerAnimatedTransitioning>
@end
两个必须的方法:
// 返回动画时间
- (NSTimeInterval)transitionDuration:
(id <UIViewControllerContextTransitioning>)transitionContext {
return 2.0;
}
// transitionContext包含获取to and from VC(view controller)s,the containing UIView等,相当于存储执行动画所需元素的集合,
// 动画执行的方法
- (void)animateTransition:
(id <UIViewControllerContextTransitioning>)transitionContext {
// 1. obtain state from the context
UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
CGRect finalFrame = [transitionContext finalFrameForViewController:toViewController];
// 2. obtain the container view
UIView *containerView = [transitionContext containerView];
// 3. set initial state
CGRect screenBounds = [[UIScreen mainScreen] bounds];
toViewController.view.frame =
CGRectOffset(finalFrame, 0, screenBounds.size.height);
// 4. add the view
[containerView addSubview:toViewController.view];
// 5. animate
NSTimeInterval duration =
[self transitionDuration:transitionContext];
[UIView animateWithDuration:duration
animations:^{
toViewController.view.frame = finalFrame;
} completion:^(BOOL finished) {
// 6. inform the context of completion
[transitionContext completeTransition:YES];
}];
}
动画执行的步骤:
使用transitionContext获取toVC和动画结束时该controller的view的位置
在动画期间,to and from VCs 的 views 保存在containerView中,需要手动将to- view加入到containerView
设置to- view的起始位置
手动将to- view加入到containerView。
开始动画,设置to- view的结束位置(从transitionContext中获取),动画的时间从animation controller代理方法1中获取。
动画结束时,通知transitionContext,
转场动画整体流程图:
2.设置转场动画代理
toVC有一个transitionDelegate属性,需要fromVC实现该代理方法。
当转场到一个toVC时,framework会先检查这个属性,判断是否执行自定义的转场动画。
@interface MasterViewController () <UIViewControllerTransitioningDelegate>
@end
代理(fromVC)将提供自定义转场动画,需要自己实现该动画。
if ([segue.identifier isEqualToString:@"ShowAbout"])
{
UIViewController *toVC = segue.destinationViewController; toVC.transitioningDelegate = self;
}
设置toVC.transitioningDelegate的代理为fromVC。在fromVC中实现动画实现。
在transitionDelegate(fromVC)代理中加入animation controller头文件(#import “BouncePresentAnimationController.h”)和animation controller的实例变量:
@implementation MasterViewController
{
BouncePresentAnimationController *_bounceAnimationController;
}
You need to implement the UIViewControllerTransitioningDelegate method that supplies this animation controller.
需要在fromVC中自己实现UIViewControllerTransitioningDelegate的方法,该方法提供转场的animation controller,animation controller中含有自定义转场动画