自定义转场动画(二)

之前介绍一篇文章 自定义转场动画(一),主要介绍了Present的转场动画。今天介绍一下有关Push的转场动画。

准备:首先要两个UIViewController和一个继承与UIPercentDrivenInteractiveTransition的类。

ViewController1

ViewController2

PushTransitionAnimator

PushTransitionAnimator
.h

@interface PushTransitionAnimator : UIPercentDrivenInteractiveTransition<UIViewControllerAnimatedTransitioning,UIViewControllerTransitioningDelegate,UIGestureRecognizerDelegate>

@property (nonatomic, assign) BOOL isPop;//是push还是pop

.m
完成UIViewControllerAnimatedTransitioning协议

- (NSTimeInterval)transitionDuration:(id)transitionContext{
    return self.transitionDuration;
}
//这里实现从下往上的Push
- (void)animateTransition:(id)transitionContext{

    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViewController   = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];

    self.targetViewController = toViewController;
    [self creatDragGesture];

    UIView *containerView = [transitionContext containerView];
    if (!self.isPop) {
        CGRect startRect;

        [containerView addSubview:toViewController.view];

        toViewController.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
        startRect = CGRectMake(0, CGRectGetHeight(containerView.bounds), CGRectGetWidth(containerView.bounds), CGRectGetHeight(containerView.bounds));

        toViewController.view.frame = startRect;

        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
            fromViewController.view.alpha = self.behindViewAlpha;
            toViewController.view.frame = CGRectMake( 0, 0,
                                                     CGRectGetWidth(toViewController.view.frame),
                                                     CGRectGetHeight(toViewController.view.frame) );
        } completion:^(BOOL finished) {
            [fromViewController endAppearanceTransition];
            [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
        }];

    }else{
        [containerView addSubview:toViewController.view];

        toViewController.view.alpha = self.behindViewAlpha;

        CGRect endRect;

        endRect = CGRectMake(0, CGRectGetHeight(fromViewController.view.frame), CGRectGetWidth(fromViewController.view.frame), CGRectGetHeight(fromViewController.view.frame));

        [toViewController beginAppearanceTransition:YES animated:YES];

        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
            toViewController.view.alpha = 1.0f;
            fromViewController.view.frame = endRect;

        } completion:^(BOOL finished) {
            [toViewController endAppearanceTransition];
            [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
        }];
    }
}

如何使用

Push与Present最直观的区别就是有导航的参与。所以我们要在ViewController1中准守 UINavigationControllerDelegate 协议。

初始化 设置导航代理

- (void)viewDidLoad {
    [super viewDidLoad];
        _animator                    = [[PXPushTransitionAnimation alloc] initWithModalViewController:self];
    _animator.dragable           = YES;
    _animator.bounces            = YES;
    _animator.behindViewAlpha    = 0.3;
    _animator.transitionDuration = 0.35f;
    _animator.behindViewScale    = 1.0f;
    ....
}
- (void)viewDidAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    self.navigationController.delegate        = self;
}

实现代理方法

#pragma mark - **************** Navgation delegate
- (id)navigationController:(UINavigationController *)navigationController
                                  animationControllerForOperation:(UINavigationControllerOperation)operation
                                               fromViewController:(UIViewController *)fromVC
                                                 toViewController:(UIViewController *)toVC
{
    if (operation == UINavigationControllerOperationPush) {
        self.animator.isPop = NO;//push
    }else if (operation == UINavigationControllerOperationPop){
        self.animator.isPop = YES;//pop
    }
    return self.animator;
}

有关手势的返回交互可以参考present,原理相同。

你可能感兴趣的:(iOS)