iOS 导航转场动画

本文介绍了如何在iOS7及以上版本中使用UIViewControllerAnimatedTransitioning协议自定义导航控制器的转场动画,包括实现交互式和非交互式的动画效果,并通过实例展示了具体代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.前言:

导航控制器的push,pop的动画默认是推过来,然后返回来,但是ios7后 就可以修改导航的转场动画了,导航,tab 都可以自定义动画  ,昨天心血来潮做了一个demo,研究的不是很深,就给自己做个笔记。

iOS7后有这个协议UIViewControllerAnimatedTransitioning 来修改转场动画 必须实现两个协议方法

// 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. 

- (NSTimeInterval)transitionDuration:(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;



2.准备:

a.两个试图控制器 

  b.一个动画类别

3.代码

appdelegate

 self.window = [[UIWindow alloc]initWithFrame:[UIScreen mainScreen].bounds];
    [self.window setBackgroundColor:[UIColor whiteColor]];
    IndexViewController *vc = [[IndexViewController alloc] init];
    UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:vc];
    self.window.rootViewController = nav;
    [self.window makeKeyAndVisible];
    return YES;

=================================================

动画类

Animator.h

实现 UIViewControllerAnimatedTransitioning协议 

/ 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. 

- (NSTimeInterval)transitionDuration:(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;

完整代码:

//
//  Animator.h
//  demo
//
//  Created by linpeng on 14-9-18.
//  Copyright (c) 2014年 linpeng. All rights reserved.

#import <Foundation/Foundation.h>

@interface Animator : NSObject <UIViewControllerAnimatedTransitioning>
@property(nonatomic)int type;
@property(nonatomic,strong)UIView *view;
@end

</pre><p style="margin-top: 0px; margin-bottom: 0px; font-size: 11px; font-family: Menlo; color: rgb(0, 132, 0);"><pre name="code" class="html">//
//  Animator.m
//  demo
//
//  Created by linpeng on 14-9-18.
//  Copyright (c) 2014年 linpeng. All rights reserved.
//

#import "Animator.h"
@interface Animator()
{
    CGRect rect;
}
@property(nonatomic,strong)UIView *snapshotView;
@end

@implementation Animator

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
    if (self.type == 0)
        return 1;
    else
        return 1;
}
-(void)setView:(UIView *)view
{
    if (_view!=view) {
        _view = view;
    }
    rect = view.frame;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController* toViewController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIViewController* fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    [[transitionContext containerView] addSubview:toViewController.view];
    toViewController.view.alpha = 0;
    
    //push
    if (self.type == 0)
    {
        [UIView animateWithDuration:[self transitionDuration:transitionContext]*(2.0/3) delay:0 usingSpringWithDamping:0.3 initialSpringVelocity:0.8 options:UIViewAnimationOptionAllowUserInteraction
                         animations:^{
                             self.view.center = CGPointMake([UIScreen mainScreen].bounds.size.width/2, [UIScreen mainScreen].bounds.size.height/2);
                             CGAffineTransform trans =  CGAffineTransformMakeScale(5,5);
                             self.view.transform = trans;
                             
                              fromViewController.view.transform = CGAffineTransformMakeScale(0.3, 0.3);
                         } completion:^(BOOL finished) {
                             
                             [UIView animateWithDuration:[self transitionDuration:transitionContext]*(1.0/3) animations:^{
                                 fromViewController.view.transform = CGAffineTransformMakeScale(0.5, 0.5);
                                 toViewController.view.alpha = 1;
                             }completion:^(BOOL finished) {
                                 fromViewController.view.transform = CGAffineTransformIdentity;
                                 self.view.transform = CGAffineTransformIdentity;
                                 self.view.frame = rect;
                                 [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
                             }];
                         }];
        
        
    }
    else//pop
    {
        [UIView animateWithDuration:[self transitionDuration:transitionContext]*(1.0/3) animations:^{
                             fromViewController.view.transform = CGAffineTransformMakeScale(2, 2);
                         } completion:^(BOOL finished) {
                             
                             [UIView animateWithDuration:[self transitionDuration:transitionContext]*(1/3.0) delay:0 usingSpringWithDamping:0.3 initialSpringVelocity:0.8 options:UIViewAnimationOptionAllowUserInteraction
                                              animations:^{
                                  fromViewController.view.transform = CGAffineTransformMakeScale(0, 0);
                             }completion:^(BOOL finished) {
                                 toViewController.view.alpha = 1;
                                 fromViewController.view.transform = CGAffineTransformIdentity;
                                 [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
                             }];
                             
                         }];
    }
    
}

@end



=================================================

IndexViewController


设置导航的代理 

//导航代理

    self.navigationController.delegate =self;


实例化动画类

//动画

    self.animalPush = [[Animatoralloc]init];

    self.animalPush.type =0;

    self.animalPop = [[Animatoralloc]init];

    self.animalPop.type =1;


然后代理里面实现

-(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC

{

    if (operation ==UINavigationControllerOperationPush)

    {

       returnself.animalPush;

    }

   else

    {

       returnself.animalPop;

    }

    return nil;

}

完整类

//
//  IndexViewController.h
//  demo
//
//  Created by linpeng on 14-9-18.
//  Copyright (c) 2014年 linpeng. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface IndexViewController : UIViewController
@end

//
//  IndexViewController.m
//  demo
//
//  Created by linpeng on 14-9-18.
//  Copyright (c) 2014年 linpeng. All rights reserved.
//

#import "IndexViewController.h"
#import "ViewController.h"
#import "Animator.h"

#define RGBCOLOR(r,g,b) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:1]
//主色调
#define kMAINCOLOR  RGBCOLOR(86,206,186)

@interface IndexViewController ()<UIViewControllerTransitioningDelegate, UINavigationControllerDelegate, UITabBarControllerDelegate>
@property(nonatomic,strong) Animator *animalPush,*animalPop;
@end

@implementation IndexViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    [self.view setBackgroundColor:[UIColor whiteColor]];
    //动画
    self.animalPush = [[Animator alloc] init];
    self.animalPush.type = 0;
    self.animalPop = [[Animator alloc] init];
    self.animalPop.type = 1;
    
    //导航代理
    self.navigationController.delegate = self;

    float w = [UIScreen mainScreen].bounds.size.width;
    for (int i = 0; i<6; i++)
    {
        UIView *view = [[UIView alloc]initWithFrame:CGRectMake((w/6+5)*i, 100, 50,50)];
        [view setBackgroundColor:kMAINCOLOR];
        [self.view addSubview:view];
    }
    
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = touches.anyObject;
    UIView *view = [touch view];
    self.animalPush.view = view;
    
    ViewController *vc = [[ViewController alloc]init];
    [self.navigationController pushViewController:vc animated:YES];
}
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
-(id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC
{
    if (operation == UINavigationControllerOperationPush)
    {
        return self.animalPush;
    }
    else
    {
        return self.animalPop;
    }
    return nil;
}


@end


=================================================

ViewController

 完整类

//
//  ViewController.h
//  demo
//
//  Created by linpeng on 14-9-18.
//  Copyright (c) 2014年 linpeng. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController
@end

//
//  ViewController.m
//  demo
//
//  Created by linpeng on 14-9-18.
//  Copyright (c) 2014年 linpeng. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self.view setBackgroundColor:[UIColor whiteColor]];
    
    UILabel *lab = [[UILabel alloc] initWithFrame:self.view.bounds];
    lab.text = @"Hello World";
    lab.textAlignment = NSTextAlignmentCenter;
    [self.view addSubview:lab];
    
    
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self.navigationController popToRootViewControllerAnimated:YES];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

效果



内容概要:本文档主要展示了C语言中关于字符串处理、指针操作以及动态内存分配的相关代码示例。首先介绍了如何实现键值对(“key=value”)字符串的解析,包括去除多余空格和根据键获取对应值的功能,并提供了相应的测试用例。接着演示了从给定字符串中分离出奇偶位置字符的方法,并将结果分别存储到两个不同的缓冲区中。此外,还探讨了常量(const)修饰符在变量和指针中的应用规则,解释了不同类型指针的区别及其使用场景。最后,详细讲解了如何动态分配二维字符数组,并实现了对这类数组的排序与释放操作。 适合人群:具有C语言基础的程序员或计算机科学相关专业的学生,尤其是那些希望深入理解字符串处理、指针操作以及动态内存管理机制的学习者。 使用场景及目标:①掌握如何高效地解析键值对字符串并去除其中的空白字符;②学会编写能够正确处理奇偶索引字符的函数;③理解const修饰符的作用范围及其对程序逻辑的影响;④熟悉动态分配二维字符数组的技术,并能对其进行有效的排序和清理。 阅读建议:由于本资源涉及较多底层概念和技术细节,建议读者先复习C语言基础知识,特别是指针和内存管理部分。在学习过程中,可以尝试动手编写类似的代码片段,以便更好地理解和掌握文中所介绍的各种技巧。同时,注意观察代码注释,它们对于理解复杂逻辑非常有帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值