APP Store首頁header效果

不知道有沒有細心的同學注意,App Store首頁、知乎發(fā)現(xiàn)也的頭部在下拉的時候是不動的,上推得時候會和列表一起無視差上滑動。如下圖。

微信
知乎
App Store

那么這些效果是怎么實現(xiàn)的呢?

分析

微信圖1
微信圖2

根據(jù)微信圖1,我們暫且假設藍色框內(nèi)部分用UICollectionView實現(xiàn)的,但是根據(jù)滑條在紅色框內(nèi)那塊視圖的下面,我們可以推斷出,紅色框內(nèi)的視圖不是注冊的UICollectionViewheaderView。他應該是直接add在我們假設的UICollectionView,或者UICollectionViewsuperView上的。
再看微信圖2滑條的位置,正好在紅色框那塊視圖的下方。這是怎么實現(xiàn)的呢?

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

就是這個接口,只要像這樣設置一下tableView.scrollIndicatorInsets.top = 130那么滑條就會偏移130pt。

知道了這個關鍵的接口,那么微信圖中的那種header效果實現(xiàn)思路就基本很清晰了。

思路

  • 通過UICollectionViewFlowLayoutheaderReferenceSize方法空出你頭部的size
  • 通過scrollIndicatorInsets這個接口設置滑條的位置
  • 把視圖添加到你的滾動視圖上

現(xiàn)在微信頭部的效果基本可以完成了,那知乎的呢?其實是差不多的,就是知乎在下拉的時候是不動的。
接著微信的那個思路,我們很容易想到在下拉的時候控制headerViewy值即可。

核心代碼

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        // 204 = headerView.frame.height + 導航欄和狀態(tài)欄高度
        let y = scrollView.contentOffset.y
        headerView.frame.origin.y = 64 - 204 - max(y, -204)
    }

我們再看App Store的那個效果。咦,他的滑條怎么在headerView上方?顯然之前的思路和這個效果相駁。

分析

  1. 如果要滿足滑條在headerView的上方的條件,那么headerView應該是加在tableHeaderView上的(有實現(xiàn)相同效果的其他方案請留言)。
  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。。。
找到了這個

在里面發(fā)現(xiàn)了這個方法

func viewDidLayoutSubviews(){}

似曾相識,但是又不是。
相信之前很多人用過這個方法

func layoutSubviews() {}

如果你不熟悉這個方法,請跳轉(zhuǎn)

第二次嘗試

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
      // 64應該為狀態(tài)欄和導航欄高度
      // automaticallyAdjustsScrollViewInsets這個屬性默認為true,一個UIScrollView在有導航欄的控制器中,坐標會從導航欄底部計算
        let y = tableView.contentOffset.y
        if y <= -64 {
            tableView.tableHeaderView?.frame.origin.y = y + 64
        }
    }

效果

AppStore.gif

Demo

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容