需求:
最近公司项目中要开发一个Scrollview嵌套多个TableView的页面。类似下图微博的这种页面。
布局结构如下图:
遇到的问题:
开发这样的结构会有一个问题就是滑动TableView到边界的时候,由于响应链问题,不会带动Scroll1继续滑动。最开始打算的是通过两个滑动视图的偏移量来设置他们的scrollEnabled
,切换响应者,以达到两个视图只有一个在滑动的目的。但是这样的话如果滑到顶部边界时,需要抬手再次进行滑动的才可以切换scrollEnabled
的状态,这种滑动不流畅的效果显然不是我需要的。
解决思路:
后来发现苹果有提供实现多个嵌套的 UIScrollView 同时响应滑动事件的方法。在父视图的ScrollView实现这个方法然后return YES
即可。
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
这样上滑时就可以首先固定TableVIew的偏移量,TableVIew滑动到顶部时再允许其滑动,然后固定ScrollVIew的偏移量,下滑同理。
主要实现代码:
在滑动到边界时,通过通知,也可以根据具体需求调整为通过代理来改变两个视图的CanScroll
状态,来实现两个视图由谁来滑动的目的。
父视图ScrollVIew的滑动代理方法:
-(void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGFloat backScrollTopOffset = self.headerHeight;
if (scrollView == self.scrollView) {
if (!_canScroll) {
//固定contentOffset,使其不滚动
self.scrollView.contentOffset = CGPointMake(0, backScrollTopOffset);
} else if (scrollView.contentOffset.y >= backScrollTopOffset) {
scrollView.contentOffset = CGPointMake(0, backScrollTopOffset);
self.canScroll = NO;
// 滑动到顶部 通知tableView改变TableView的CanScroll状态
[[NSNotificationCenter defaultCenter] postNotificationName:@"TableCanScroll" object:nil];
}
}
}
子视图TableVIew的滑动代理方法:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (!self.tableCanScroll) {
scrollView.contentOffset = CGPointZero;
} else if (scrollView.contentOffset.y <= 0) {
self.tableCanScroll= NO;
//通知ScrollView改变ScrollView的CanScroll状态
[[NSNotificationCenter defaultCenter] postNotificationName:@"ScrollCanScroll" object:nil];
}
}