前言
在移動應用實際開發過程中,往往會有多個scrollview嵌套的界面需求,這種需求已經司空見慣,解決方案也多種多樣,這里就介紹一下我認為最優的解決方案。
效果圖:
結構解讀:
底層有一個UIScrollview子類,這里叫它mainScrollview;
mainScrollview下方嵌套了兩個視圖(通常這兩個視圖也用UIScrollview子類來處理,這里叫它moduleScrollview)。
毫無疑問,我們通常的做法是在mainScrollview的下方先嵌套一個橫向滾動的UIScrollview子類,再在這個橫向滾動的視圖上嵌套n個子模塊(像gif中的“圖文詳情”和“客戶評分”兩個子模塊)。
這點我不做過多解釋,結構的搭建爭議不大,重點在交互上。
嘗試過的思路:
有一種思路總結起來是,通過開啟或者禁止mainScrollview和moduleScrollview的交互來達到何時響應某個scrollview的目的。在手指拖動的臨界狀態,通過大量的判斷邏輯來主動控制某些scrollview的偏移量,進而達到“欺騙觀眾”的響應拖動狀態。
缺點:邏輯復雜程度過大,容錯處理很多,致命的缺陷是臨界狀態無法實現scrollview的減速效果(慣性效果),當然有的開發者會說利用核心動畫能實現這一效果,但是,我認為這就太費周折了。
最佳方案:
首先我們來了解一個UIGestureRecognizerDelegate協議擬定的方法:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
這個方法的作用大致可以理解為是否允許手勢穿透。在iOS開發中,相同的手勢,響應者往往是最上層的視圖,所以重寫這個方法返回為YES就可以讓下層的視圖響應同樣的手勢。
值得注意的是,UIScrollview實現了這個協議的方法,所以,我們可以讓子模塊直接繼承UIScrollview(或其子類),然后重寫該方法。
如此一來,我們需要做的,僅僅是判斷何時不讓某個scrollview改變偏移量即可。
優點:實現簡單,絲滑無卡頓
核心思想:讓moduleScrollview 和mainScrollview 同時響應上拉或者下拉手勢,只需判斷何時不允許某個scrollview改變contentOffset
DEMO
GitHub地址:https://github.com/indulgeIn/YBMultistageScrollView
注意:DEMO中嵌套進了UIWebview,并簡單做了邏輯處理方案,會有性能問題