美文网首页iOS开发 UI类
iOS 在控制器间跳转实现过渡动画(补充)

iOS 在控制器间跳转实现过渡动画(补充)

作者: 吾名唐宋 | 来源:发表于2019-03-15 17:20 被阅读0次

本文主要依赖于飘金-iOS 在控制器间跳转实现过渡动画的文章, 文章介绍了两个方法, 一个是简单的系统方法, 就是开篇的跳转前, 设置keyWindow的layer, 这个demo相信自己写出来没难度.

然后我在看第二个方法的时候, 有点疑问, 就那个UIViewControllerAnimatedTransitioning, 这玩意到底写在哪, 主要是蒙了, 然后我搜到了另一篇文章不会抽烟-iOS UIViewControllerAnimatedTransitioning 自定义转场动画, 开头直言: 1.自定义转场:继承NSObject,并遵循UIViewControllerAnimatedTransitioning协议。, 然后才反应过来.

现在整理了一下整个动画过程
首先, 主界面跳转页面, 我们正常操作(采纳协议<UIViewControllerTransitioningDelegate>获取跳转过程中的方法)

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NewToViewController *toVC = [[NewToViewController alloc] init];
    // 因为我需要拿到这个跳转过程,
    // 所以设置代理, 实现UIViewControllerTransitioningDelegate协议方法
    toVC.transitioningDelegate = self;
    [self presentViewController:toVC animated:YES completion:nil];
}

实现代理方法

// 这个协议里面有好几个方法, 基本差不多, 看自己需要
- (nullable id <UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
    return [NewAnimationTransition new];
}

以下截取原文, 如果你要带导航的专场效果, 请参考

@protocol UINavigationControllerDelegate

这是修改Navigation跳转动画需要实现的协议,当我们通过pop或者push进行跳转时,都会调用下面的方法(协议的其他方法由于暂时用不到,所以就不介绍了),我们可以看到返回值是id <UIViewControllerAnimatedTransitioning>,就是我们之前编写的动画对象。
- (nullable id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                               animationControllerForOperation:(UINavigationControllerOperation)operation
                                            fromViewController:(UIViewController *)fromVC
                                              toViewController:(UIViewController *)toVC;

方法中的operation参数是一个枚举类型,我们可以判断它的值是 UINavigationControllerOperationPush还是
UINavigationControllerOperationPop来区别当前的跳转方式。

这个转场对象怎么来的呢?

新建一个转场对象NewAnimationTransition, 继承自NSObject, 采纳协议<UIViewControllerAnimatedTransitioning>

@interface NewAnimationTransition : NSObject<UIViewControllerAnimatedTransitioning>
@end

.m实现代码, 首先是UIViewControllerAnimatedTransitioning协议的两个方法, 这个飘金-iOS 在控制器间跳转实现过渡动画里面写的比我详细, 如果想看代码释义可以看这个

//这个方法中我们只要返回页面跳转动画的执行时间
-(NSTimeInterval)transitionDuration:(id < UIViewControllerContextTransitioning >)transitionContext {
    return 0.5;
}
//在这个方法中实现具体动画
-(void)animateTransition:(id < UIViewControllerContextTransitioning >)transitionContext {
    // 方法中的参数transitionContext是当前临时控制器界面的上下文。
    self.transitionContext = transitionContext;
    // 通过上下文,我们先拿到临时视图控制器的背景视图containerView,他已经有一个子视图,即fromViewController.view。
    // 我们要做的是,先获得toViewController
    UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    [[transitionContext containerView] addSubview:toVC.view];
    
    // 要实现Demo里的效果,我们需要CAShapeLayer来给toView做遮挡,
    // 然后从修改ShapeLayer.path属性,从一个小圆变成一个囊括全屏的大圆,小圆大圆我们通过UIBezierPath画出来
    
    CGFloat kWindowH = [UIScreen mainScreen].bounds.size.height;
    CGFloat kWindowW = [UIScreen mainScreen].bounds.size.width;
    CGRect circleCenterRect = CGRectMake(120, kWindowH, 50, 50);
    //圆圈1--小圆
    UIBezierPath *smallCircleBP =  [UIBezierPath bezierPathWithOvalInRect:circleCenterRect];
    //圆圈2--大圆
    //以_circleCenterRect的中心为圆心
    CGFloat centerX = circleCenterRect.origin.x+circleCenterRect.size.width/2;
    CGFloat centerY = circleCenterRect.origin.y+circleCenterRect.size.height/2;
    //找出圆心到页面4个角 最长的距离 作为半径
    CGFloat r1 = (kWindowW-centerX)>centerX?(kWindowW-centerX):centerX;
    CGFloat r2 = (kWindowW-centerY)>centerY?(kWindowW-centerY):centerY;
    CGFloat radius = sqrt((r1 * r1) + (r2 * r2));
    UIBezierPath *bigCircleBP = [UIBezierPath bezierPathWithOvalInRect:CGRectInset(circleCenterRect, -radius, -radius)];
    //    画完圆后通过CABasicAnimation执行:
    
    //设置maskLayer
    CAShapeLayer *maskLayer = [CAShapeLayer layer];//将它的 path 指定为最终的 path 来避免在动画完成后会回弹
    toVC.view.layer.mask = maskLayer;
    maskLayer.path = bigCircleBP.CGPath;
    //执行动画
    CABasicAnimation *maskLayerAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
    maskLayerAnimation.fromValue = (__bridge id)(smallCircleBP.CGPath);
    maskLayerAnimation.toValue = (__bridge id)((bigCircleBP.CGPath));
    maskLayerAnimation.duration = [self transitionDuration:transitionContext];
    maskLayerAnimation.delegate = self;
    [maskLayer addAnimation:maskLayerAnimation forKey:@"path"];
    
}

然后该对象采纳协议, 就是<CAAnimationDelegate>
实现方法

- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag{
    //告诉 系统这个 transition 完成
    [self.transitionContext completeTransition:![self.transitionContext transitionWasCancelled]];
    //清除 fromVC 的 mask
    [self.transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey].view.layer.mask = nil;
    [self.transitionContext viewControllerForKey:UITransitionContextToViewControllerKey].view.layer.mask = nil;
}

以上是转场动画对象

到这, 我们跳转页面, 然后自定义转场动画就搞定
然后我顺便把第一种系统自带的方法, 放在demo里面, 一起看吧

演示.gif

界面丑陋, 担待, 主要就是想做个demo出来, 自带界面, 我随机采用一种动画效果, label显示的就是效果名称, 这个你们自己去研究吧

demo地址-https://github.com/LiuZhangpeng/TestAnimations

相关文章

  • 2018-07-05

    iOS 在控制器间跳转实现过渡动画 可以使用CALayer下的CATransition动画在同一个控制器下实现,但...

  • iOS 在控制器间跳转实现过渡动画(补充)

    本文主要依赖于飘金-iOS 在控制器间跳转实现过渡动画的文章, 文章介绍了两个方法, 一个是简单的系统方法, 就是...

  • iOS 在控制器间跳转实现过渡动画

    简单自定义ViewController跳转动画 在学习iOS动画时看到,别人炫酷的动画效果一直是我学习的动力,在学...

  • iOS-动画相关

    本篇涵盖各种直播动画,跳转,过渡动画等. 1.分享iOS中实现navigationController全屏手势滑动...

  • Swift 好用的动画库

    Hero - 为了构建 iOS 试图控制器过渡动画的库。它在 UIKit 繁琐的过渡动画 API 之上提供了一个层...

  • iOS7之转场动画

    iOS7添加了转场动画,让我们更加方便的切换控制器。 iOS7 SDK支持两种自定义过渡:自定义视图控制器过渡和交...

  • Unity动画综合练习

    前言:对于融合树、状态机(动画状态参数、过渡线)、角色控制器、动画控制器的综合练习 1.实例:使用动画融合树实现原...

  • iOS动画指南 - 6.可以很酷的转场动画

    在iOS开发中,界面间的跳转其实也就是控制器的跳转,跳转有很多种,最常用的有push,modal. modal:任...

  • iOS跳转到qq聊天界面

    补充 :因iOS10之后,上面的跳转到qq客户端的,方式已经不能实现(不灵了 不能正常跳转)以下方式是可以在iOS...

  • Day15. Redux的使用

    补充 过渡动画和axios的补充 CSSTransition SwitchTransition Transitio...

网友评论

    本文标题:iOS 在控制器间跳转实现过渡动画(补充)

    本文链接:https://www.haomeiwen.com/subject/wydrmqtx.html