前言
實際開發過程中,總會使用到新浪微博個人主頁這種頁面形式。下面是我的實現思路和過程。
頁面介紹講解
圖一默認狀態
圖二置頂狀態
如 圖一默認狀態
個人主頁我們分成兩大區域綠色(A)和紅色(B+C)區域;
綠色區域A我們叫他Header
,紅色區域我們叫他Body
;其中較爲複雜的Body分爲segement
欄(B)和類似tableView
的(C)組成,而且B很明顯類似一個UIPageViewController
。
分解思路:
(1)Header
可以根據項目需要自己寫 View,非常簡單,不多做介紹
(2)Body
本次調研使用WMPageController
實現
(3)聲明實例化一個UIScrollView*
類型的containerScrollView
屬性作爲superView
添加Header
和Body
,使ABC可以作爲一個整體滑動;
交互過程和痛點
(1)滑動tableView
C時分兩種情況圖一默認狀態
和圖二置頂狀態
(2)圖一默認狀態
時滑動tableView
C,tableView不會滑動(tableView
的contentOffset
不會改變)
(3)直到segement
欄(B)滑動到導航欄底部時,tableView
C才真正可以滑動(contentOffset
大於0
)。
(4)在(3)至此之後,再將手指下滑頁面,當tableView
C的contentOffset
迴歸0
,segement
欄(B)開始偏離導航欄。
上面是交互過程並不複雜,但是將過程(1)(2)(3)僅用手指一次完成(保持連續性)是這次需求的痛點:
【1】如果手指一開始在C上滑動,那麼滑動手勢會被C的tableView
所攔截,ABC不會作爲一個整體更隨便宜,而我們是需要B和導航欄相接時才讓C的tableView
開始響應滑動事件!這是多數人做這個需求時候遇到的第一大難題!
【2】爲了解決【1】很多人會先讓C的tableView
的scrollEnabled
爲NO
,等到B和導航欄相接時才讓C的tableView
的scrollEnabled
爲YES
;那你就順利進入了另一個坑,還是"將過程(1)(2)(3)僅用手指一次完成(保持連續性)"這個問題,當你手指在C的tableView上開始往上滑動,等到B和導航欄相接時才讓C的tableView
的scrollEnabled
從NO
變成YES
的過程中會出現另一個問題,scrollEnabled
狀態切換會導致手勢的中斷。所以這種方法不可行。
解決方法
懂得多的同學可能知道協議@protocol UIGestureRecognizerDelegate <NSObject>
有一個方法。返回一個BOOL可以用來決定是否響應多個手勢,默認返回是NO。我們創建一個UIScrollView
的子類MultiResponseScrollView
,然後遵循協議,並時下如下代碼,注意返回值YES;
/**
同時識別多個手勢
@param gestureRecognizer gestureRecognizer description
@param otherGestureRecognizer otherGestureRecognizer description
@return return value description
*/
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
前面提到聲明的實例containerScrollView
,我們就讓他的類型從UIScrollView
改成MultiResponseScrollView
。然後你就可以發現:在圖一默認狀態
狀態時,手指在C的tableView上開始往上滑動時,containerScrollView
竟然也收到了滑動的手勢,所以結果是 C的tableView
和containerScrollView
一起在滑動。(到這裏如果沒有接觸過上面這個協議方法的同學建議可以開始寫一寫代碼了,光看不寫是不行的,對說的就是你!)
哈哈哈到這裏,我們已經實現了這個交互的一半的效果了,而另一半的工作就是要解決:
【1】上面(在segement
欄(B)還沒和導航欄相接時)只讓containerScrollView
滑動而不是C的tableView
也跟着一起滑動。
【2】再進一步的說,當圖二置頂狀態
再將手指下滑頁面,先讓containerScrollView
不滑動直到tableView
C的contentOffset
迴歸0
。
【3】當tableView
C的contentOffset
迴歸0
,再讓containerScrollView
響應滑動,ABC整體下移。
以上三步距可以在UIScrollViewDelegate的-scrollViewDidScroll:
中實現。
好了,到這裏我已經提供了最大痛點的解決思路,本來是想下面寫上部分代碼實現,但是時間原因(忙啊!我也沒辦法ಥ_ಥ)和爲了讓各位自己練手(笑),暫且就先不寫了哈哈哈哈。如果你有疑問歡迎在下面回覆我。如果點贊人數多或者問題回覆比較多的話我後面考慮抽時間整理一份頁面框架的工具代碼。