转场动画

控制器的转场动画

  众所周知,iOS中的页面跳转方式有两种,一种是navigationController push/pop新页面,另一种是当前页面present/dismiss新页面

  1. push/pop 转场动画

    系统默认的push动画是从右往左推出新视图,pop则是从左往右消失

    自定义实现步骤

      a.控制器实现nagationController delegate的方法animationControllerForOperation:fromController:toController,返回一个实现了UIViewControllerAnimatedTransitionning对象,如果返回为nil,则是系统的默认实现

- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
    if ([NSStringFromClass(fromVC.class) isEqualTo:]) {
    return [CustomTransitioning new];
  }
    return nil;
}

      b.自定义实现UIViewControllerAnimatedTransitioning协议的对象,实现自定义转场

@interface XWPageCoverTransition : NSObject<UIViewControllerAnimatedTransitioning>

@end

@implementation XWPageCoverTransition

- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext{
    return 0.3;
}
/**
 *  如何执行过渡动画
 */
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext{
    
}

@end

       必须实现该协议的两个方法

      transitionDuration:  返回转场时间

      animationTransition:  转场动画的具体操作,以一个简单的例子来说明如何实现

// 从下到上显示
- (void)showFromBottomToTop:(id<UIViewControllerContextTransitioning>)transitionContext {
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UIView *containerView = [transitionContext containerView];
    CGRect toVCFrame = [transitionContext finalFrameForViewController:toVC];
    [containerView addSubview:toVC.view];
    [containerView sendSubviewToBack:toVC.view];
    //对tempView做动画,避免bug;
    UIView *tempView = [toVC.view snapshotViewAfterScreenUpdates:YES];
    tempView.frame = CGRectOffset(toVCFrame, 0, SCREEN_HEIGHT);
    [containerView addSubview:tempView];
    //增加阴影
    tempView.layer.shadowOffset = CGSizeMake(0, 1);
    tempView.layer.shadowColor = [UIColor lightGrayColor].CGColor;
    tempView.layer.shadowOpacity = 0.8;
    [UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
        tempView.frame = toVCFrame;
    } completion:^(BOOL finished) {
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
        [tempView removeFromSuperview];
        [containerView bringSubviewToFront:toVC.view];
    }];
}

       以上代码是自定义push从下到上显示,该方法包含一个transitionContext对象,我们来看看该对象的几个重要属性

       -containerView 包含上下文的容器,动画在该容器中进行

       -viewControllerForKey  获取fromVC/toVC

       -finalFrameForViewController 获取fromVC/toVC的最终展示frame

       一般的做法是根据转场类型push/pop做相应处理,通常是frame,alpha的的简单变化,也可以做复杂点的三维变化。

       如果是push动画,A->B,fromVC是A,toVC是B;pop B,fromVC是B,toVC是A。每次变换container中必须添加toVC.view,截取该视图,对截取的视图做相应动画,动画结束后,恢复原始状态即可。

  2.present/dismiss动画,默认的是从下到上呈现,以及从上到下消失

      自定义实现步骤:

      1.自定义的页面需要声明UIViewControllerTransitionningDelegate,并设置modelPresentationStyle为custom,同事还需实现相关的代理方法

@interface XWPresentedOneController ()<UIViewControllerTransitioningDelegate>
@property (nonatomic, strong) XWInteractiveTransition *interactiveDismiss;
@property (nonatomic, strong) XWInteractiveTransition *interactivePush;
@end

@implementation XWPresentedOneController

- (void)dealloc{
    NSLog(@"销毁了!!!!!");
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        self.transitioningDelegate = self;
        self.modalPresentationStyle = UIModalPresentationCustom;
    }
    return self;
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source{
    return [XWPresentOneTransition transitionWithTransitionType:XWPresentOneTransitionTypePresent];
}

- (id<UIViewControllerAnimatedTransitioning>)animationControllerForDismissedController:(UIViewController *)dismissed{
    return [XWPresentOneTransition transitionWithTransitionType:XWPresentOneTransitionTypeDismiss];
}

- (id<UIViewControllerInteractiveTransitioning>)interactionControllerForDismissal:(id<UIViewControllerAnimatedTransitioning>)animator{
    return _interactiveDismiss.interation ? _interactiveDismiss : nil;
}

- (id<UIViewControllerInteractiveTransitioning>)interactionControllerForPresentation:(id<UIViewControllerAnimatedTransitioning>)animator{
    XWInteractiveTransition *interactivePresent = [_delegate interactiveTransitionForPresent];
    return interactivePresent.interation ? interactivePresent : nil;
}

@end

       UIViewControllerTransitionDelegate重要方法介绍

       - animationControllerForPresentedController:  present返回实现<UIViewControllerTransitioning>对象

       - animationControllerForDismissedController:    返回自定义的dimiss对象

       - interactionControllerForPresentation:     present返回百分比动画

       - interactionControllerForDismissal:       dismiss返回百分比动画

       百分比(交互式)动画,需定义UIPercentDrivenInteractiveTransition子类,绑定pan手势,根据手势的相应状态传递事件,本质上还是调用自定义实现的transition方法,因此没个transition完成动画的闭包中会有相应代码来回应交互式状态

/开始动画吧,使用产生弹簧效果的动画API
    [UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0 usingSpringWithDamping:0.55 initialSpringVelocity:1.0 / 0.55 options:0 animations:^{
        //首先我们让vc2向上移动
        toVC.view.transform = CGAffineTransformMakeTranslation(0, -400);
        //然后让截图视图缩小一点即可
        tempView.transform = CGAffineTransformMakeScale(0.85, 0.85);
    } completion:^(BOOL finished) {
        //使用如下代码标记整个转场过程是否正常完成[transitionContext transitionWasCancelled]代表手势是否取消了,如果取消了就传NO表示转场失败,反之亦然,如果不是用手势的话直接传YES也是可以的,我们必须标记转场的状态,系统才知道处理转场后的操作,否者认为你一直还在,会出现无法交互的情况,切记
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
        //转场失败后的处理
        if ([transitionContext transitionWasCancelled]) {
            //失败后,我们要把vc1显示出来
            fromVC.view.hidden = NO;
            //然后移除截图视图,因为下次触发present会重新截图
            [tempView removeFromSuperview];
        }
    }];

 

UIView的转场动画

  1.直接调用系统api  [UIView transitionWithView:duration:option:animation:^{}completion:^{}]

  - transitionView  需要转场到的视图

  - duration     动画时间

  - option      转场类型

  - aniamtion    动画块

  - completion    动画结束回调

UIViewAnimationOptionTransitionNone           // default
UIViewAnimationOptionTransitionFlipFromLeft   // 从左翻转
UIViewAnimationOptionTransitionFlipFromRight  // 从右翻转
UIViewAnimationOptionTransitionCurlUp         // 向上翻页
UIViewAnimationOptionTransitionCurlDown       // 向下翻页
UIViewAnimationOptionTransitionCrossDissolve  // 溶解
UIViewAnimationOptionTransitionFlipFromTop    // 从上翻转
UIViewAnimationOptionTransitionFlipFromBottom // 从下翻转

   2.使用CATransition 创建相应的animation,view.layer添加后直接在layer上渲染

   CATransition的基本属性,以下属性均可以使用kvc调用

   - type   转场类型

   - subtype   转场的子类型

   - duration  动画时间

   - timeFunction  动画加速度

//    type  
    *1.kCATransitionMoveIn 新的视图把旧的视图掩盖

     *2.kCATransitionPush 旧的视图移走,新的视图移进来

     *3.kCATransitionFade 逐渐消失,相当于调整透明度,除了这没有方向,其他的都有

     *4.kCATransitionReveal 旧的视图移走,显示出新的视图

//这类是API引入的,在苹果官网是不会承认的,所以不建议使用

      *1.animation.type = @"cube"; //立方体效果

     *2.animation.type = @"suckEffect";//犹如一块布被抽走

     *3. animation.type = @"oglFlip"; //上下翻转效果

     *4. animation.type = @"rippleEffect"; //滴水效果

     *5. animation.type = @"pageCurl"; //向左翻页

     *6.animation.type = @"pageUnCurl"; //向下翻页

//    subtype

kCATransitionFromBottom

kCATransitionFromLeft

kCATransitionFromRight

kCATransitionFromTop

//    timeFunction

CA_EXTERN CAMediaTimingFunctionName const kCAMediaTimingFunctionLinear

CA_EXTERN CAMediaTimingFunctionName const kCAMediaTimingFunctionEaseIn

CA_EXTERN CAMediaTimingFunctionName const kCAMediaTimingFunctionEaseOut

CA_EXTERN CAMediaTimingFunctionName const kCAMediaTimingFunctionEaseInEaseOut

CA_EXTERN CAMediaTimingFunctionName const kCAMediaTimingFunctionDefault

 

转载于:https://www.cnblogs.com/xiaoerheiwatu/p/9992939.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值