iOS自定义转场动画的实现

iOS中熟悉的是导航栏中的push和pop这两种动画效果,在这里我们可以自己实现自己想要的一些转场动画

下面是我自己创建转场动画的过程

1、新建一个文件继承自NSObject ,遵循协议UIViewControllerAnimatedTransitioning,

2、添加一个枚举,用于判断视图的推入还是推出

typedef enum {
    AnimationTypePresent,
    AnimationTypeDismiss
} AnimationType;并申明一个属性 @property (nonatomic, assign) AnimationType type;

3、在.m中分别实现下面的两个协议方法

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext;
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext;
- (void)animationEnded:(BOOL)transitionCompleted;
//前两个方法是必须实现的,
#pragma mark -动画执行的时间

-(NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
    return 0.40;
}

#pragma mark -执行具体的动画

-(void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
    //拿到相关的视图层次
    UIView *containerView = [transitionContext containerView];
    UIViewController *fromViewController = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toViweController = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    if (self.type == AnimationTypePresent) {
        toViweController.view.transform = CGAffineTransformMakeScale(0.0, 0.0);
        [containerView insertSubview:toViweController.view aboveSubview:fromViewController.view];
        //添加动画
        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
            toViweController.view.transform = CGAffineTransformMakeScale(1.0, 1.0);
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
    }else{
        //将to视图插入到from视图的底部
        [containerView insertSubview:toViweController.view belowSubview:fromViewController.view];
        
        //放大from视图直到他消失
        [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
            fromViewController.view.transform = CGAffineTransformMakeScale(0.0, 0.0);
        } completion:^(BOOL finished) {
            [transitionContext completeTransition:YES];
        }];
    }
    
}

#pragma mark -动画执行完毕

- (void)animationEnded:(BOOL)transitionCompleted;

4、实现了这些方法之后在你想要跳转的地方引入这个NSObject类的头文件,定义一个全局变量并初始化

self.navigationController.delegate = self;实现导航栏的代理以及协议

5、在这两个方法中都要返回自己定义个那个全局变量

#pragma mark - 跳转开始的动画协议push过去的动画
-(id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{
//    return _animationFade;
    return _animationScale;
}
#pragma mark -pop回来的动画
-(id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed{
    return _animationScale;
    
}

6、判断视图是推入还是推出

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

//不同类型对应不同的动画效果
        case UINavigationControllerOperationPush:
           _animationScale.type = AnimationTypePresent;
           return _animationScale;
            break;
        case UINavigationControllerOperationPop:
            _animationScale.type = AnimationTypeDismiss;
            return _animationScale;
            break;
    }
    return nil;
}

自定义转场动画学习站:

iOS7教程系列:自定义导航转场动画以及更多

objc系列译文(12.3):自定义View Controller容器转场

上一篇:第二百九十五天 how can i 坚持


下一篇:Windows Server 2016-Netdom Join之客户端加域(二)