iOS7自定义视图控制器过渡1-动作过渡

24 篇文章 0 订阅
前言:视图控制器的过渡是发生在俩个视图控制器切换的过程中,在这一时间段内,我们利用SDK中提供的方法做出炫目的动画,提高用户体验。自定义视图控制器过渡分为两种:动作事件过渡和手势交互过渡。这篇中先介绍简单点的动作事件过渡,手势交互在下一篇中介绍。


正文:

现在我们举个列子来介绍实现动作事件过渡的方法。该例子最终效果如下:

最终效果

1. 我们先创建俩个视图控制器,一个是ViewController(蓝色的那个),另一个是RedViewController(红色的那个。

----ViewController.m----
@interface ViewController ()<UIViewControllerTransitioningDelegate>
@property (nonatomic, strong) PresentAnimater *presentAnimater;
@property (nonatomic, strong) DismissAnimater *dismissAnimater;
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.presentAnimater = [[PresentAnimater alloc] init];
    self.dismissAnimater = [[DismissAnimater alloc] init];
    self.view.backgroundColor = [UIColor blueColor];
    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    button.frame = CGRectMake(80.0, 210.0, 160.0, 40.0);
    [button setTitle:@"Click me" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
}
- (void)buttonClicked:(UIButton *)btn
{
    RedViewController *redVC = [[RedViewController alloc] init];
    redVC.delegate = self;
    redVC.transitioningDelegate = self;
    [self presentViewController:redVC animated:YES completion:nil];
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source
{
    return self.presentAnimater;
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed
{
    return self.dismissAnimater;
}

---RedViewController.m---
@implementation RedViewController

- (void)viewDidLoad {
    [super viewDidLoad];    self.view.backgroundColor = [UIColor redColor];
    
    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 {
    [self dismissViewControllerAnimated:YES completion:nil];
}

(1) 如果需要执行自定义过渡效果,就要设置transitionDelegate代理对象

该代理需要实现以下俩个方法:

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed

分别返回呈现(present)视图控制器时的动画对象和解散(dismiss)视图控制器时的动画对象,具体的动画细节需要在动画对象中实现,动画对象需要服从UIViewControllerAnimatedTransitioning协议。第一个方法在[selfpresentViewController:redVCanimated:YEScompletion:nil];之后被调用,第二个方法在[selfdismissViewControllerAnimated:YEScompletion:nil];之后被调用。


2. 创建呈现视图控制器时的动画对象(present视图控制器时的过渡动画效果)

----PresentAnimater.m-----
@implementation PresentAnimater
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
    return 0.4;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    // 1. 获取源控制器和目标控制器
    UIViewController *scVc = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toVc = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    // 2. 添加目标控制器的view
    CGRect scFrame = scVc.view.frame;
    CGRect toFrame = scFrame;
    toFrame.origin.x = toFrame.size.width;
    toVc.view.frame = toFrame;
    
    UIView *containerView = [transitionContext containerView];
    [containerView addSubview:toVc.view];
    
    // 3. 动画 源控制器的View缩小 --> 目标控制器推入
    CGFloat boder = 20;
    CGFloat duration = [self transitionDuration:transitionContext];
    [UIView animateWithDuration:duration animations:^{
        scVc.view.alpha = 0.5f;
        scVc.view.frame = CGRectMake(boder, boder, scFrame.size.width - 2 * boder, scFrame.size.height - 2 * boder);
        toVc.view.frame = scFrame;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:YES];
    }];
}

(1) UIViewControllerAnimatedTraning协议是用来指定动画细节,一定要实现以下2个方法:

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext

前者返回动画执行的时间,后者实现过渡中的具体动画效果。 transitionContext是过渡过程中的上下文,可以从中获取源视图控制器(fromVc)、目标视图控制器(toVc)等参数。

(2)动画执行完成后一定要有这句[transitionContextcompleteTransition:YES];这句话是告诉系统过渡动画完成,系统会自动做些后续的清理工作。如果不写,将无法再次切换视图控制器。

3. 创建解散视图控制器时的动画对象(dismiss视图控制器时的过渡动画效果)

<span style="font-size:14px;">@implementation DismissAnimater
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext
{
    return 0.4;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UIViewController *scVc = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toVc = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    CGRect scFrame = scVc.view.frame;
    CGRect toFrame = scFrame;
    toFrame.origin.x = scFrame.size.width;
    
    toVc.view.frame = CGRectInset(scFrame, 20, 20);
    
    UIView *containerView = [transitionContext containerView];
    [containerView addSubview:toVc.view];
    [containerView sendSubviewToBack:toVc.view];
    
    CGFloat duration = [self transitionDuration:transitionContext];
    [UIView animateWithDuration:duration animations:^{
        scVc.view.frame = toFrame;
        toVc.view.frame = scFrame;
        toVc.view.alpha = 1;
    } completion:^(BOOL finished) {
        // NO : 会还原动画前所有View的位置。
        [transitionContext completeTransition:YES];
    }];
}</span>


和呈现视图控制器动画对象一样,就不再赘述。


demo地址--点击打开链接

动作事件过渡的实现方法很简单,但是手势交互过渡稍微复杂点,下一篇我们再说。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值