46

转场动画-仿AppStore跳转及抖音评论

 5 years ago
source link: http://www.cocoachina.com/ios/20190426/26882.html?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

有钱的捧个钱场,没钱的捧个人场,看一看瞧一瞧嘞。

RZvI3iI.gif

YnUJJrn.gif

demo下载地址:

demo-0

demo-1

demo-0为简化版,方便大家理解。demo-1为优化版,功能代码都比demo-0多一些,本文主要以demo-1进行讲解。

前言

在写这个demo之前我以为转场动画就像女神一样,离我很远,日常的项目中根本接触不到,毕竟系统自带的就好用了,身轻体柔易推倒。但好的动画效果就像电影彩蛋一样,不经意间给用户一个惊喜,这对App的拉新传播都很有帮助。而且程序员在写出后,不仅可以在测试女神面前秀一把操作,还可以让自己的老板在投资人面前标榜自己的团队质量,拉到更多的资金,从而弯道超车让自己升职加薪,走上人生巅峰。

国内在交互这方面做的比较好的公司有很多,比如腾讯和字节跳动。因为我这个demo主要是写AppStore跳转和抖音评论,所以就研究了下【AppStore】、【抖音】、【QQ音乐】这三个产品。

接下来我言简意赅,就此demo的实现过程,过程中进行产品相互的对比,对比产生问题进行一番描述。

1.转场动画基本概念

转场动画主要是由*转场动画*,*跳转协议*,*手势交互*三部分组成。

转场动画是对动画效果的代码描述,且遵守UIViewControllerAnimatedTransitioning协议。

跳转协议是在push,press等协议的相关方法里,返回动画对象。

手势交互就是用手势来控制动画的进度,一般都是建立UIPercentDrivenInteractiveTransition的子类。

我这里就转场动画的基本概念不进行过多的描述,网上相关的资料非常多。

2.AppStore效果

AppStore首页的动画主页分为这几个部分。

2.1 视图部分

长按,视图缩小,松开后,视图铺开进入下个界面且有轻微弹簧效果。

点击,视图缩小,松开后,视图铺开进入下个界面且有轻微弹簧效果。

长按后滑动,视图先缩小,然后恢复原状。

我这里直接用UIButton处理这些手势,touchesBegan处理视图缩小,touchesEnded处理点击回调。所以在这里加了个bool属性endTouchesBegan用来判断视图是否已经缩小。如果缩小,直接回调,没有则先进行缩小载回调。

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
    self.endTouchesBegan =NO;
    [UIView animateWithDuration:0.2 animations:^{
        self.btn.transform = CGAffineTransformMakeScale(0.97,0.97);
    } completion:^(BOOL finished){
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(0.2 * NSEC_PER_SEC)),dispatch_get_main_queue(),^{
            self.endTouchesBegan =YES;
        });
    }];
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    if(self.endTouchesBegan){
        if(self.block){
            self.block();
        }
    }else{
        [UIView animateWithDuration:0.2 animations:^{
            self.btn.transform = CGAffineTransformMakeScale(0.97,0.97);
        } completion:^(BOOL finished){
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(0.2 * NSEC_PER_SEC)),dispatch_get_main_queue(),^{
                if(self.block){
                    self.block();
                }
            });
        }];
    }
}
-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{
    [UIView animateWithDuration:0.2 animations:^{
        self.btn.transform = CGAffineTransformIdentity;
    }];
}

2.2 statusBar部分

AppStore动画第一个界面的statusBar为显示,第二个界面隐藏,第三个界面恢复显示。我们用bool属性hideStatus判断显示隐藏。

第一个界面,默认self.hideStatus =NO,进行显示。当点击图片时,调用strongSelf.hideStatus =YES进行隐藏;这样做的目的是,当由第二个界面pop回来时,statusBar先是隐藏的,然后走下面这个方法,进行statusBar动画显示。

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    self.hideStatus =NO;
    [UIView animateWithDuration:0.5 animations:^{
        [self setNeedsStatusBarAppearanceUpdate];
    }];
}

同理,第二个界面也是这样处理,但是第二个界面不知道是push进去还是pop进去的,所以增加了push属性。

2.3 tabBar部分

tabBar动画开始想用hidesBottomBarWhenPushed进行隐藏,但是与AppStore转场动画不太搭,所以就仿照AppStore的tabBar的动画在UINavigationControllerDelegate协议方法里面进行了处理。

//消失
if(2 == navigationController.viewControllers.count){
       CGRect tabRect = navigationController.tabBarController.tabBar.frame;
        navigationController.tabBarController.tabBar.frame = CGRectMake(tabRect.origin.x,TLDeviceHeight -tabRect.size.height,tabRect.size.width,tabRect.size.height);
        [UIView animateWithDuration:0.5 animations:^{
            navigationController.tabBarController.tabBar.frame = CGRectMake(tabRect.origin.x,TLDeviceHeight +tabRect.size.height,tabRect.size.width,tabRect.size.height);
        } completion:^(BOOL finished){
            navigationController.tabBarController.tabBar.hidden =YES;
        }];
}
//出现
if(1 == navigationController.viewControllers.count){
        if(navigationController.tabBarController.tabBar.hidden){
           CGRect tabRect = navigationController.tabBarController.tabBar.frame;
            navigationController.tabBarController.tabBar.frame = CGRectMake(tabRect.origin.x,TLDeviceHeight +tabRect.size.height,tabRect.size.width,tabRect.size.height);
            navigationController.tabBarController.tabBar.hidden =NO;
            [UIView animateWithDuration:0.5 animations:^{
                navigationController.tabBarController.tabBar.frame = CGRectMake(tabRect.origin.x,TLDeviceHeight -tabRect.size.height,tabRect.size.width,tabRect.size.height);
            }];
        }
}

2.4 pop手势

AppStore转场pop手势的上下滑动跟抖音评论的效果非常类似,但与之对比,AppStore页面还增加了左滑pop手势。

我开始是想用苹果自带边缘手势UIScreenEdgePanGestureRecognizer来进行处理,但发现这样只能解决横向侧滑pop,无法解决竖向滑动pop的问题。索性就自己写了一套手势,横向竖向都能支持。横向的滑动还支持全屏,半屏等距离属性的设置,写了全局的宏TLPanEdgeInside来控制。

手势处理自认为比AppStore与抖音评论的效果还好。因为无论AppStore还是抖音评论,只能朝上或朝下其中一个方向改变,要么改变UIScrollView的偏移量,要么改变控制器pop的进度。而我封装的这套可以上下自由改变,并且可以监测开始的手势,由上下滑转左右滑,还是按照上下为基础。

biu6zyE.gif

2.5 后续问题

2.5.1 防止重复点击

因为push转场时间为0.8秒,我在第一个控制器加入了以下userEnabled属性用来防止重复点击问题。详情见demo的代码。

2.5.2 分类方法实现

AppStore转场主要涉及三个方法的重写:

-(NSArray*_Nonnull)tl_transitionUIViewFrameViews;
-(NSString *_Nonnull)tl_transitionUIViewImage;
-(void)setContainScrollView:(UIScrollView *)scrollView isPush:(BOOL)isPush;

第一个方法是涉及前一个视图和后一个视图里面动画控件的回调。

第二个主要就是图片资源的回调。

第三个就是为了防止手势冲突,将所需要规避冲突的UIScrollView视图传入进去。

2.5.3 导航栏出现隐藏

导航栏出现隐藏的判断是在UINavigationControllerDelegate协议里面判断的,但是考虑到项目中有些并不是所有的页面都需要转场动画,所以UINavigationControllerDelegate协议在两个地方进行了重写。并且还在UIViewController的分类中重写的viewWillAppear中进行了判断,方便常规push和转场push的自由切换。

- (void)swizzViewWillAppear:(BOOL)animated{

    if (TLAnimationUIViewFrame == self.animationType || TLAnimationWindowScale == self.animationType || TLAnimationAppStore == self.animationType) {
        
        self.navigationController.interactivePopGestureRecognizer.delegate = [TLPushTransitionDelegate shareInstance];
        self.navigationController.delegate = [TLPushTransitionDelegate shareInstance];
        [TLPushTransitionDelegate shareInstance].popController = self;
    
    }else{
    }
    
    [self swizzViewWillAppear:animated];
}

3.仿抖音评论

3.1 抖音评论

抖音评论手势的处理和AppStore的一模一样。只不过AppStore是push,抖音评论是press。

这里有个链接是跟抖音的一模一样, DouYinComment 。这个demo是基于视图层级弹窗,而我写的是弹出控制器。

同时为了避免快速轻扫产生的闪动,我手势结束事件加了一个判断,当速度过快,轻扫的距离过短的时候,直接进行pop或者dismiss。

if((TLPanDirectionEdgeLeft ==self.startDirection || TLPanDirectionEdgeRight ==self.startDirection)&&[gesture velocityInView:gesture.view].x>= 250){

//左右轻扫,快速返回
        [self finishInteractiveTransition];
        [self.disMissController dismissViewControllerAnimated:YES completion:nil];
    
    }else if((TLPanDirectionEdgeUp ==self.startDirection || TLPanDirectionEdgeDown ==self.startDirection)&&self.scrollView.contentOffset.y <= 0="" tlpandirectionedgeup="=" directiontype="" gesture="" .y="">= 250){

    //上下轻扫,快速返回
        [self finishInteractiveTransition];
        [self.disMissController dismissViewControllerAnimated:YES completion:nil];
    
    }else{
    
    //正常返回
        if(percentComplete > 0.3f){
            [self finishInteractiveTransition];
        }else{
            [self cancelInteractiveTransition];
        }
}

YFnAJjI.gif

qIjeQny.gif

YjaAfmi.gif

因为在手机录制不能检测到手势光标,所以就用 DouYinComment 代替抖音在模拟器进行录制。大家可以看到,抖音评论当手指滑出弹框外面的时候,它是以弹框整体偏移量为基础滚动,而我是按照里面的UIScrollView偏移量为基础,个人认为第二种效果更好。

3.1 QQ音乐

在研究转场动画时候,注意到QQ音乐有个界面存在一个小问题,就是使用加藤鹰般的手速上下滑动的时候,此界面和顶部空隙会越来越大。应该是手势和界面偏移量之间处理的问题。

aMvUryF.gif

4.其他两种效果

4.1 视图位移

fiYVzqm.gif

这种效果挺好看的,处理起来也非常简单。只需把相应的控件传入转场动画里面就行。而且图片浏览功能也可以这样进行封装。

4.2 视图缩小

MbYfQnj.gif

这个也很简单,不过一般用于没有导航栏的界面,不然看起来会比较丑。

简书地址: https://www.jianshu.com/p/c3742d607d43

如果大家有什么疑问或者建议,欢迎评论。

如需转载,请告知本人,谢谢。


Recommend

  • 193
    • 掘金 juejin.im 7 years ago
    • Cache

    Android转场动画一说

    Android转场动画一说 所谓转场动画,通俗的讲就是一个Activity跳转到另一个Activity是的动画。 Activity的转场动画很早就有了,5.0之前用的是overridePendingTransition()这个方法。在5.0之后,Google使用Material D...

  • 72
    • www.cocoachina.com 6 years ago
    • Cache

    移动应用里的转场动画

  • 48
    • www.cocoachina.com 6 years ago
    • Cache

    炫酷转场动画-iOS

  • 65
    • 掘金 juejin.im 6 years ago
    • Cache

    Android 转场动画

    转场动画 转场动画: 是Android L 引入的动画效果, 可以说是api19引入的场景(Scene)动画的扩展. 使开发者更加方便的实现布局(界面)变化时候的过渡动画. Android L 是Google于2014年升级的系统版本号, 在2015年国内厂商

  • 43
    • www.cocoachina.com 6 years ago
    • Cache

    iOS 自定义转场动画

    自定义转场动画集锦.gif 本文记录分享下自定义转场动画的实现方法,具体到动画效果:新浪...

  • 42
    • www.sunyazhou.com 6 years ago
    • Cache

    iOS抖音的转场动画 | 東引甌越

  • 61

    byzhangxinxu from https://www.zhangxinxu.com/wordpress/?p=8643 本文欢迎分享与聚合,全文转载就不必了,尊重版权,圈子就这么大,若急用可以联系授权。...

  • 12
    • 微信 mp.weixin.qq.com 4 years ago
    • Cache

    舒服了~玩转Android转场动画!

    者:下位子 https://juejin.cn/post/6880409898363027463 先直接上效果图: 相信...

  • 13
    • www.androidchina.net 3 years ago
    • Cache

    Android Reveal圆形Activity转场动画

    Android Reveal圆形Activity转场动画 – Android开发中文站你的位置:Android开发中文站 > Android开发 >

  • 7
    • www.androidchina.net 3 years ago
    • Cache

    Android转场动画的前世今生

    前一段时间做图片查看器的升级时,在打开图片查看器的时,找不到好的过渡方式。 医生推荐了Android最新的Material Motion动画,虽然最终没有给我们的App安排,但给我学习Material Motion动画提供了...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK