如果你已经厌倦了使用UINavigationController进行简单粗暴的push和pop转场操作,你完全可以使用自定义的导航转场效果,iOS7提供了许多漂亮的代理方法帮助你实现各种自定义动画,下面演示一个简单的导航转场动画Demo的实现过程,效果如图一所示:
STEP 1: 创建一个项目,其中包含,一个名为FirstViewController和一个SecondViewController的视图控制器,两个继承自NSObject的PopAnimation和PushAnimation类。
STEP2:使用UIViewControllerAnimatiedTransitioning代理方法自定义Push 动画
1.)让PopAnimation使用UIViewControllerAnimatedTransitioning代理的方法:
- @interface PushAnimation : NSObject <UIViewControllerAnimatedTransitioning>
- - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
- UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
- UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
- [[transitionContext containerView] addSubview:toViewController.view];
- toViewController.view.alpha = 0;
- [UIView animateWithDuration:0.3*[self transitionDuration:transitionContext] animations:^{
- fromViewController.view.transform = CGAffineTransformMakeScale(0.6, 0.6);
- toViewController.view.alpha = 0.3;
- } completion:^(BOOL finished) {
- [UIView animateWithDuration:0.3*[self transitionDuration:transitionContext] animations:^{
- fromViewController.view.transform = CGAffineTransformMakeScale(1.1, 1.1);
- toViewController.view.alpha = 0.6;
- } completion:^(BOOL finished){
- [UIView animateWithDuration:0.4*[self transitionDuration:transitionContext] animations:^{
- fromViewController.view.transform = CGAffineTransformMakeScale(0.1, 0.1);
- toViewController.view.alpha = 1.0;
- } completion:^(BOOL finished){
- fromViewController.view.transform = CGAffineTransformIdentity;
- [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
- }];
- }];
- }];
- }
- - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
- return 3.0f;
- }
STEP 3: 使用UIViewControllerAnimatiedTransitioning代理方法自定义Pop 动画
- @interface PopAnimation : NSObject <UIViewControllerAnimatedTransitioning>
- - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
- UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
- UIViewController *toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
- [[transitionContext containerView] addSubview:toViewController.view];
- toViewController.view.alpha = 0;
- toViewController.view.transform = CGAffineTransformMakeScale(0.1, 0.1);
- [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
- toViewController.view.transform = CGAffineTransformMakeScale(1.0, 1.0);
- toViewController.view.alpha = 1.0f;
- fromViewController.view.alpha = 0.0f;
- } completion:^(BOOL finished) {
- fromViewController.view.transform = CGAffineTransformIdentity;
- [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
- }];
- }
- - (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
- return 3.0f;
- }
STEP4: 在FirstViewController中实现UINavigationControllerDelegate的一些方法
- #import "PushAnimation.h"
- @interface FirstViewController : UIViewController <UINavigationControllerDelegate>
- @property (nonatomic, strong) PushAnimation *animation;
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- _animation = [PushAnimation new];
- //隐藏NavigationBar
- self.navigationController.navigationBarHidden = YES;
- //设置背景图片
- UIImageView *imageView = [[UIImageView alloc]initWithFrame:self.view.frame];
- [imageView setImage:[UIImage imageNamed:@"1.jpg"]];
- [self.view addSubview:imageView];
- //定义一个button
- UIButton *pushBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
- pushBtn.frame = CGRectMake(284, 700, 200, 40);
- [pushBtn setTitle:@"push" forState:UIControlStateNormal];
- pushBtn.titleLabel.font = [UIFont systemFontOfSize:32.0f];
- [pushBtn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
- [self.view addSubview:pushBtn];
- }
- - (void)viewDidAppear:(BOOL)animated {
- [super viewDidAppear:animated];
- self.navigationController.delegate = self;
- }
- - (void)viewWillDisappear:(BOOL)animated {
- [super viewWillDisappear:animated];
- if (self.navigationController.delegate == self) {
- self.navigationController.delegate = nil;
- }
- }
- - (void)buttonClicked:(id)sender {
- SecondViewController *presentController = [[SecondViewController alloc]init];
- [self.navigationController pushViewController:presentController animated:YES];
- }
- #pragma mask UINavigationControllerDelegate
- - (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
- animationControllerForOperation:(UINavigationControllerOperation)operation
- fromViewController:(UIViewController *)fromVC
- toViewController:(UIViewController *)toVC {
- if (operation == UINavigationControllerOperationPush) {
- return self.animation;
- }
- return nil;
- }
STEP5: 在SecondViewController中调用PopAnimation动画
- @interface SecondViewController : UIViewController <UINavigationControllerDelegate>
- @property(nonatomic, strong) PopAnimation *animation;
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- _animation = [PopAnimation new];
- //隐藏NavigationBar
- self.navigationController.navigationBarHidden = YES;
- //设置背景图片
- UIImageView *imageView = [[UIImageView alloc]initWithFrame:self.view.frame];
- [imageView setImage:[UIImage imageNamed:@"2.jpg"]];
- [self.view addSubview:imageView];
- //定义一个button
- UIButton *pushBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
- pushBtn.frame = CGRectMake(284, 700, 200, 40);
- [pushBtn setTitle:@"Pop" forState:UIControlStateNormal];
- pushBtn.titleLabel.font = [UIFont systemFontOfSize:32.0f];
- [pushBtn addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
- [self.view addSubview:pushBtn];
- }
- - (void)viewDidAppear:(BOOL)animated {
- [super viewDidAppear:animated];
- self.navigationController.delegate = self;
- }
- - (void)viewWillDisappear:(BOOL)animated {
- [super viewWillDisappear:animated];
- if (self.navigationController.delegate == self) {
- self.navigationController.delegate = nil;
- }
- }
- - (void)buttonClicked:(id)sender {
- [self.navigationController popViewControllerAnimated:YES];
- }
- #pragma mask UINavigationControllerDelegate
- - (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
- animationControllerForOperation:(UINavigationControllerOperation)operation
- fromViewController:(UIViewController *)fromVC
- toViewController:(UIViewController *)toVC {
- if (operation == UINavigationControllerOperationPop) {
- return self.animation;
- }
- return nil;
- }
STEP6: Over 了