最近项目迭代了一个新的版本,由于我们的设计师是虾米音乐的忠实粉丝,首页借鉴了虾米8.0首页的视差动画,在预研实现过程中有一些值得记录和分享的地方
虾米音乐8.0首页鉴赏
先看看虾米首页最终的展示效果,搜索栏会随着内容视图滚动偏移渐隐,内容视图有一个视差滚动的效果,达到滚动阈值后搜索栏会隐藏。
细心的同学可能会发现,Banner与导航栏滚动的速度相同,所以实现的难点,是如何实现Banner图与导航栏的相对静止,同时在表视图滚动到既定偏移量时,Banner图被表视图遮盖的效果。
页面结构分析
从呈现结果来看,整个视图可以分为两个部分,导航视图(CusNavigationView)及内容视图(MainContentView)。
导航视图同时包含了一个自定义搜索栏(SearchBar),自定义二级导航栏(NavigationBarLevel2),这个二级导航栏的实现我会单独写一篇博客来讲。
内容视图是一个表视图(TableView),以及使用表视图的头视图来添加轮播图(BannerView):
1 | ┏ CusNavigationView |
此处导航视图为了更好监听MainContentView的滚动偏移对子视图进行控制,没有使用系统的NavigationBar,而采用了自定义的方式。
让我们实现她!
在开始编写逻辑前,先根据上个Section分析的视图结构,声明相关视图属性及导航栏折叠前高度与折叠后高度
1 |
|
首先先实现视差滚动效果,我们通过实现ScrollView代理,监听滚动事件,通过计算折叠动画内滚动进度比的方式,控制各个视图的相关属性,达到视差效果,代码如下
1 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView{ |
光实现了视差滚动还不够,如果滚动到一半位置会出现半遮半掩的效果,非常影响体验,于是我们新建一个名为magneticScrollView:
的方法,用于控制在结束滚动时进行视图检查,如果进度比在0~1之间,则根据既定阈值调整视图位置,达到弹性效果
1 | - (void)magneticScrollView:(UIScrollView *)sc{ |
该方法如果在滚动视图存在减速的情况下,则在减速完成后调用,若不存在减速,则直接调用
1 | - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ |
那么,虾米8.0首页一个视差效果简单的demo就完成了,核心代码的代码量不到100行。当然,实际的业务需求肯定没有这么简单,重要的是一种实现思路。代码传送门