UIViewControllerTransitioningDelegate
controller modal过渡的presented和dismiss的动画交互协议,你需要实现协议,它会询问你:
- 当PresentedController时,你要使用怎样的动画类(UIViewControllerAnimatedTransitioning)展示过渡效果?
- 当DismissedController时,你要使用怎样的动画类(UIViewControllerAnimatedTransitioning)展示过渡效果?
- 当PresentedController时,你要使用怎样的过渡交互类(UIViewControllerInteractiveTransitioning)处理过渡交互?
- 当DismissedController时,你要使用怎样的过渡交互类(UIViewControllerInteractiveTransitioning)处理过渡交互?
- presentationControllerForPresentedViewController:这篇文章没有用到,应该是自定义modal状态呈现和被呈现的controller,类似于controller的PresentationStyle
UIViewControllerAnimatedTransitioning
过渡动画效果的具体实现的接口,需要实现它的3个方法,即可完成一个controller过渡动画效果
- (void)animationEnded:(BOOL) transitionCompleted{}//过渡动画完成后要执行的代码可以写到这个方法中 - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{}//具体过渡动画都在这个方法里面实现,在这个方法中可以通过transitionContext拿到一切你需要的对象 - (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext{}//过渡动画完成后要执行的代码可以写到这个方法中
UINavigationControllerDelegate
controller 非模态状态下的的过渡动画,就不能使用之前说的那个
UIViewControllerTransitioningDelegate
委托解决了,就需要用UINavigationControllerDelegate
,接口方法比较类似,但也不完全一样- 你要使用怎样的动画类(UIViewControllerAnimatedTransitioning)展示过渡效果?
- 你要使用怎样的过渡交互类(UIViewControllerInteractiveTransitioning)处理过渡交互?
- willShowViewController,didShowViewController : 生命周期事件
- navigationControllerSupportedInterfaceOrientations: 屏幕支持的方向
UIViewControllerInteractiveTransitioning
这个类用于实现在转场过路效果中的交互,比如在demo中,用它实现了一个手指下滑解除modal状态的效果
UIViewControllerContextTransitioning
UIViewControllerAnimatedTransitioning协议的关键方法
animateTransition(transitionContext: UIViewControllerContextTransitioning)
里面可以得到,使用transitionContext可以获取一些重要的上下文信息,比如前后的controller,转换时的容器等controller modal过渡效果
我们先来实现一个简单的示例,点击一个按钮,出现一个modal controller,自定义从下往上弹出并且有些回弹效果的过渡动画。从这个例子中我们可以了解
- 如何实现UIViewControllerTransitioningDelegate
- 如何实现UIViewControllerAnimatedTransitioning
- 如何组合在一起完成功能
// // ViewController.m // UIViewControllerAnimateDemo // // Created by zhangcheng on 15/12/6. // Copyright © 2014年 zhangcheng. All rights reserved. // #import "ViewController.h" #import "ModalViewController.h" #import "PresentedAnimation.h" @interface ViewController ()<ModalViewControllerDelegate,UIViewControllerTransitioningDelegate> @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor]; UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom]; btn.frame = CGRectMake(100, 100, 100, 50); [btn setTitle:@"push" forState:UIControlStateNormal]; [btn setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; [btn addTarget:self action:@selector(Transitioning2) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:btn]; } - (void)Transitioning2{ ModalViewController *modalVC = [[ModalViewController alloc]init]; modalVC.delegate = self; modalVC.transitioningDelegate =self; [self presentViewController:modalVC animated:YES completion:nil]; } - (void)modalViewControllerDidClickedDismissButton:(ModalViewController *)viewController{ [self dismissViewControllerAnimated:YES completion:nil]; } - (id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { return [PresentedAnimation new]; } @end
// // PresentedAnimation.h // UIViewControllerAnimateDemo // // Created by zhangcheng on 15/12/6. // Copyright © 2014年 zhangcheng. All rights reserved. // #import <Foundation/Foundation.h> #import <UIKit/UIKit.h> @interface PresentedAnimation : NSObject<UIViewControllerAnimatedTransitioning> @end
// // PresentedAnimation.m // UIViewControllerAnimateDemo // // Created by zhangcheng on 15/12/6. // Copyright © 2014年 zhangcheng. All rights reserved. // #import "PresentedAnimation.h" #import "ViewController.h" #import "ToViewController.h" @implementation PresentedAnimation - (instancetype)init{ if (self == [super init]) { } return self; } - (NSTimeInterval)transitionDuration:(nullable id <UIViewControllerContextTransitioning>)transitionContext{ return 0.8f; } - (void)animateTransition:(id <UIViewControllerContextTransitioning>)transitionContext{ UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; CGRect screenBounds = [UIScreen mainScreen].bounds; CGRect finalFrame = [transitionContext finalFrameForViewController:toVC]; toVC.view.frame = CGRectOffset(finalFrame, 0, screenBounds.size.height); UIView *containerView = [transitionContext containerView]; [containerView addSubview:toVC.view]; NSTimeInterval duration = [self transitionDuration:transitionContext]; [UIView animateWithDuration:duration delay:0.0 usingSpringWithDamping:0.6 initialSpringVelocity:0.0 options:UIViewAnimationOptionTransitionCurlUp animations:^{ toVC.view.frame = finalFrame; } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; } - (void)animationEnded:(BOOL) transitionCompleted{ NSLog(@"animation ended"); } @end
// // ModalViewController.h // UIViewControllerAnimateDemo // // Created by zhangcheng on 15/12/6. // Copyright © 2014年 zhangcheng. All rights reserved. // #import <UIKit/UIKit.h> @class ModalViewController; @protocol ModalViewControllerDelegate <NSObject> -(void) modalViewControllerDidClickedDismissButton:(ModalViewController *)viewController; @end @interface ModalViewController : UIViewController @property (nonatomic, weak) id<ModalViewControllerDelegate> delegate; @end
// // ModalViewController.m // UIViewControllerAnimateDemo // // Created by zhangcheng on 15/12/6. // Copyright © 2014年 zhangcheng. All rights reserved. // #import "ModalViewController.h" @interface ModalViewController () @end @implementation ModalViewController - (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor lightGrayColor]; UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0); [button setTitle:@"Dismiss me" forState:UIControlStateNormal]; [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:button]; } - (void)buttonClicked:(UIButton *)btn{ if ([self.delegate respondsToSelector:@selector(modalViewControllerDidClickedDismissButton:)]) { [self.delegate modalViewControllerDidClickedDismissButton:self]; } } @end