主要需求如上图。
1、通过自定义ScrollView实现自带panGesture的代理方法:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
if ([gestureRecognizer isKindOfClass:NSClassFromString(@"UIScrollViewPanGestureRecognizer")] && [otherGestureRecognizer isKindOfClass:NSClassFromString(@"UIScrollViewPanGestureRecognizer")]) { return YES; } return NO;}
存在问题:
当tableView或者collectionView内嵌在ScrollView中时,会失去上下bounce的效果,不能实现下拉刷新的功能
解决方式是将collectionView包在另一个scrollView中,并将scrollView的scrollEnable设置为NO
2、分别实现最外层scrolLView和内层CollectionView的- (void)scrollViewDidScroll:(UIScrollView *)scrollView方法,实现控制内外层滑动时机。
外层scrollView
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGPoint offset = scrollView.contentOffset; if (offset.y<=0) { //如果外层达到最小偏移量,外层保持不动 scrollView.contentOffset = CGPointZero; self.PK_canScroll = NO; }else if (offset.y<=_roofViewHeight){ if(self.PK_homeCollectionView.contentOffset.y>0) { //如果内层存在偏移,外层保持不动 scrollView.contentOffset = CGPointMake(0, _roofViewHeight); self.PK_canScroll = NO; }else if(self.PK_homeCollectionView.contentOffset.y<0) { //如果内层存在偏移,外层保持不动 scrollView.contentOffset = CGPointMake(0, 0); self.PK_canScroll = NO; }else{ //外层可以滑动 self.PK_canScroll = YES; } }else{ //如果外层达到最大偏移量,外层保持不动 scrollView.contentOffset = CGPointMake(0, _roofViewHeight); self.PK_canScroll = NO; }}
内层collectionView
- (void)scrollViewDidScroll:(UIScrollView *)scrollView { CGPoint offset = scrollView.contentOffset; if (self.PK_floorScrollView.PK_canScroll) { //外层可以滑动时,内层保持不动 scrollView.contentOffset = CGPointZero; }else{ //外层固定,外层在被上拉到最大和下拉到最大的状态,外层上拉到最大时,内层不能下拉;外层下拉到最大时,内层不能上拉 if (offset.y>0) { //内层上拉,如果外层下拉最大状态,则内层不动 if (self.PK_floorScrollView.contentOffset.y==0) { scrollView.contentOffset = CGPointZero; } }else{ //内层下拉,如果外层上拉最大状态,则内层不动 if (self.PK_floorScrollView.contentOffset.y>0) { scrollView.contentOffset = CGPointZero; } } }}