代碼地址:https://github.com/BigDad3/scrollviews
里面的代碼一共有兩種實現(xiàn)方式,其中第二種還存在tableview上拉加載的問題沒有解決。這篇文章主要是解釋一下第一種實現(xiàn)方法的思路,想具體了解的話還是下載源碼自己研究一下比較好。
首先來說一個整個的視圖結(jié)構(gòu)吧,Controller的View上有個一個Scrollview作為最下面的BottomScrollview,BottomScrollview 上面是一個View來展示一些內(nèi)容,下面是一個subScrollView里面會橫向排列N個tableview用來展示內(nèi)容。每個tableview都會有下拉刷新跟上拉加載。大概的結(jié)構(gòu)構(gòu)如下所示,希望你們能明白…

需要一個連貫的動作,也就是手指不抬起來,切換響應(yīng)者。整個的效果如下所示:(重點需要注意的是手指不抬起來,整個過程手指都沒有抬起來,再一個難點就是下拉刷新在中間)。

思路1: 通過判斷contentOffset位置,來切換BottomScrollview的scrollEnabled和tableview的scrollEnable來達到不同的scrollview響應(yīng)滑動手勢的目的。
最后結(jié)果:行不通
原因:手指不抬起來的時候沒辦法切換響應(yīng)者。當(dāng)開始響應(yīng)手勢的時候響應(yīng)者就確定了,手指不離開屏幕整個過程不會中斷,也就是響應(yīng)者不會切換。
當(dāng)滑動到一定的位置,這個時候
需要BottomScrollview(BottomScrollview. scrollEnabled = no)不在滑動,改為tableview(BottomScrollview. scrollEnabled = yes)來響應(yīng)滑動手勢去滑動的時候,BottomScrollview雖然不動了,但是tableview也不會動
,因為這時候BottomScrollview還是響應(yīng)者。
思路2:Scrollview上的手勢都是UIGestureRecognizer的子類,內(nèi)部實現(xiàn)了UIGestureRecognizerDelegate的相關(guān)函數(shù),通過重載UIGestureRecognizerDelegate的相關(guān)函數(shù)是不是可以控制手勢的響應(yīng)者呢?
結(jié)果:失敗
原因:原因同上,響應(yīng)者沒辦法切換。
思路3:既然切換手勢的響應(yīng)者的思路行不通,只能通過控制BottomScrollview和tableview的位置來達到效果了,也就是contentOffset的設(shè)置,來達到效果。開始響應(yīng)手勢之處呢就必須讓兩個scrollview(BottomScrollview和tableview)都要響應(yīng)手勢,只不過有一個動了有一個沒動([tableview setContentOffset:CGPointZero];),到了另一個情況呢就會切換這個操作也就是[BottomScrollview setContentOffset:CGPointZero];。
結(jié)果:可行。
具體實現(xiàn):
創(chuàng)建UIScrollView和UITableView的子類,重載函數(shù)
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
這個函數(shù)返回YES的話,手勢不只自己會響應(yīng),還會傳遞下去。達到我們同時響應(yīng)手勢的目的。
.h文件
@interface SuperTableView : UITableView
@end
.m文件
@implementation SuperTableView
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
@end
然后整個響應(yīng)過程的控制呢是在
-
(void)scrollViewDidScroll:(UIScrollView *)scrollView里完成的。具體代碼如下:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { if (scrollView == superTableView) { SubTableView * tableview; for (UIView * view in [subScrollView subviews]) { if ([view isMemberOfClass:[SubTableView class]] && view.tag == 100+positionNum) { tableview = (SubTableView *)view; } } //記錄手指在屏幕拖動的位置,如果是滑動手指離開屏幕之后值不會改變 CGPoint point = [scrollView.panGestureRecognizer translationInView:scrollView]; if (point.y > beginPoint.y) { //下滑 if (tableview.position == 0 && superTableView.position == 0) { } if (tableview.position == 0 && superTableView.position == 1) { [tableview setContentOffset:CGPointZero]; if (superTableView.contentOffset.y <= 0) { superTableView.position = 0; } } if (tableview.position == 0 && superTableView.position == 2) { [tableview setContentOffset:CGPointZero]; superTableView.position = 1; } if (tableview.position == 1 && superTableView.position == 2) { [superTableView setContentOffset:CGPointMake(0, HEADER_VIEW_HEIGHT)]; if (tableview.contentOffset.y <= 0) { tableview.position = 0; } } if (tableview.position == 2 && superTableView.position == 2) { } } else if (point.y < beginPoint.y){ //上滑 if (tableview.position == 0 && superTableView.position == 0) { [tableview setContentOffset:CGPointZero]; superTableView.position = 1; } if (tableview.position == 0 && superTableView.position == 1) { [tableview setContentOffset:CGPointZero]; if (superTableView.contentOffset.y >= HEADER_VIEW_HEIGHT) { superTableView.position = 2; [superTableView setContentOffset:CGPointMake(0, HEADER_VIEW_HEIGHT)]; } } if (tableview.position == 0 && superTableView.position == 2) { [superTableView setContentOffset:CGPointMake(0, HEADER_VIEW_HEIGHT)]; tableview.position = 1; } if (tableview.position == 1 && superTableView.position == 2) { [superTableView setContentOffset:CGPointMake(0, HEADER_VIEW_HEIGHT)]; } if (tableview.position == 2 && superTableView.position == 2) { } } beginPoint = point; } }
我定義了一個position的值來記錄scrollview的位置,0 正常狀態(tài),就是剛進入界面時候的狀態(tài),此時只能下滑 1是出于中間狀態(tài)此時可以上滑也可以下滑 2 滑到了最頂端的狀態(tài),此時只能往下滑。
比如當(dāng)下滑的時候此時BottomScrollview的position值為1,tableview的position位置為0,這個時候BottomScrollview響應(yīng)滑動手勢,tableview不響應(yīng),代碼如下
if (tableview.position == 0 && BottomScrollview.position == 1) {
[tableview setContentOffset:CGPointZero];
if (BottomScrollview.contentOffset.y <= 0) {
BottomScrollview.position = 0;
}
}