内容简介:有钱的捧个钱场,没钱的捧个人场,看一看瞧一瞧嘞。
有钱的捧个钱场,没钱的捧个人场,看一看瞧一瞧嘞。
demo下载地址:
demo-0demo-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的进度。而我封装的这套可以上下自由改变,并且可以监测开始的手势,由上下滑转左右滑,还是按照上下为基础。
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]; } }
因为在手机录制不能检测到手势光标,所以就用 DouYinComment 代替抖音在模拟器进行录制。大家可以看到,抖音评论当手指滑出弹框外面的时候,它是以弹框整体偏移量为基础滚动,而我是按照里面的UIScrollView偏移量为基础,个人认为第二种效果更好。
3.1 QQ音乐
在研究转场动画时候,注意到QQ音乐有个界面存在一个小问题,就是使用加藤鹰般的手速上下滑动的时候,此界面和顶部空隙会越来越大。应该是手势和界面偏移量之间处理的问题。
4.其他两种效果
4.1 视图位移
这种效果挺好看的,处理起来也非常简单。只需把相应的控件传入转场动画里面就行。而且图片浏览功能也可以这样进行封装。
4.2 视图缩小
这个也很简单,不过一般用于没有导航栏的界面,不然看起来会比较丑。
简书地址: https://www.jianshu.com/p/c3742d607d43
如果大家有什么疑问或者建议,欢迎评论。
如需转载,请告知本人,谢谢。
以上所述就是小编给大家介绍的《转场动画-仿AppStore跳转及抖音评论》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- iOS-转场动画
- iOS 自定义转场动画
- TransitionAnimation自定义转场动画
- iOS 自定义转场动画
- iOS抖音的转场动画
- LearningAVFoundation之视频合成+转场过渡动画
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Introduction to Linear Optimization
Dimitris Bertsimas、John N. Tsitsiklis / Athena Scientific / 1997-02-01 / USD 89.00
"The true merit of this book, however, lies in its pedagogical qualities which are so impressive..." "Throughout the book, the authors make serious efforts to give geometric and intuitive explanations......一起来看看 《Introduction to Linear Optimization》 这本书的介绍吧!