APP Store首页header效果

作者: xiAo__Ju | 来源:发表于2017-01-18 18:07 被阅读915次

    不知道有没有细心的同学注意,App Store首页、知乎发现也的头部在下拉的时候是不动的,上推得时候会和列表一起无视差上滑动。如下图。

    微信 知乎 App Store

    那么这些效果是怎么实现的呢?

    分析

    微信图1 微信图2

    根据微信图1,我们暂且假设蓝色框内部分用UICollectionView实现的,但是根据滑条在红色框内那块视图的下面,我们可以推断出,红色框内的视图不是注册的UICollectionViewheaderView。他应该是直接add在我们假设的UICollectionView,或者UICollectionViewsuperView上的。
    再看微信图2滑条的位置,正好在红色框那块视图的下方。这是怎么实现的呢?

    open var scrollIndicatorInsets: UIEdgeInsets // default is UIEdgeInsetsZero. adjust indicators inside of insets
    

    就是这个接口,只要像这样设置一下tableView.scrollIndicatorInsets.top = 130那么滑条就会偏移130pt。

    知道了这个关键的接口,那么微信图中的那种header效果实现思路就基本很清晰了。

    思路

    • 通过UICollectionViewFlowLayoutheaderReferenceSize方法空出你头部的size
    • 通过scrollIndicatorInsets这个接口设置滑条的位置
    • 把视图添加到你的滚动视图上

    现在微信头部的效果基本可以完成了,那知乎的呢?其实是差不多的,就是知乎在下拉的时候是不动的。
    接着微信的那个思路,我们很容易想到在下拉的时候控制headerViewy值即可。

    核心代码

        func scrollViewDidScroll(_ scrollView: UIScrollView) {
            // 204 = headerView.frame.height + 导航栏和状态栏高度
            let y = scrollView.contentOffset.y
            headerView.frame.origin.y = 64 - 204 - max(y, -204)
        }
    

    我们再看App Store的那个效果。咦,他的滑条怎么在headerView上方?显然之前的思路和这个效果相驳。

    分析

    1. 如果要满足滑条在headerView的上方的条件,那么headerView应该是加在tableHeaderView上的(有实现相同效果的其他方案请留言)。
    2. 如果又要满足下拉时headerView不动,那么他又不应该是加在tableHeaderView,因为tableHeaderView的坐标是不能改的。(因为我们知道的太少了,所以改不了)

    思考

    如果满足一,肯定满足不了二。满足二又不满足一。我的脑子里最开始是这么想的。
    再对两个条件比较,想要满足滑条在视图上方我只有条件一那种方式做的到,只要我在合适的地方修改到tableHeaderView的位置就能满足条件二了。

    第一次尝试

          override func scrollViewDidScroll(_ scrollView: UIScrollView) {
            let y = scrollView.contentOffset.y
            tableView.tableHeaderView?.frame.origin.y = 64 - 204 - max(y, -204)
           }
    
    

    显然是失败的。
    Google。。。
    找到了这个

    在里面发现了这个方法

    func viewDidLayoutSubviews(){}
    

    似曾相识,但是又不是。
    相信之前很多人用过这个方法

    func layoutSubviews() {}
    

    如果你不熟悉这个方法,请跳转

    第二次尝试

        override func viewDidLayoutSubviews() {
            super.viewDidLayoutSubviews()
          // 64应该为状态栏和导航栏高度
          // automaticallyAdjustsScrollViewInsets这个属性默认为true,一个UIScrollView在有导航栏的控制器中,坐标会从导航栏底部计算
            let y = tableView.contentOffset.y
            if y <= -64 {
                tableView.tableHeaderView?.frame.origin.y = y + 64
            }
        }
    

    效果

    AppStore.gif

    Demo

    相关文章

      网友评论

        本文标题:APP Store首页header效果

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