关于这个嵌套滑动问题,苹果并不推荐嵌套滚动视图,如果直接添加的话,就会出现手势的冲突造成了体验上的悲剧。目前网上大部分的方法都是自己写手势监听,实现起来太过繁琐,最近遇到了同样的问题,写了一个比较简单的方法
通过scrollView的代理方法
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
来控制内外嵌套scrollView的滚动 以及滚动到目标位置后 把后续的滚动传递给另一个scrollView 避免滚动终止的生硬。
不过这里在目标节点处 拖拽时会存在中断的情况 需要优化
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
dome实现代码
@interface ScrollViewController ()<UIScrollViewDelegate>
@property(nonatomic, strong)UIScrollView *outScrollerView;
@property(nonatomic, strong)UIScrollView *inerScrollerView;
@end
@implementation ScrollViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.outScrollerView.frame = CGRectMake(10, 90, 300, 500);
self.outScrollerView.contentSize = CGSizeMake(300, 1800);
[self.view addSubview:self.outScrollerView];
self.inerScrollerView.frame = CGRectMake(10, 440, 240, 300);
self.inerScrollerView.contentSize = CGSizeMake(240, 800);
[self.outScrollerView addSubview:self.inerScrollerView];
self.inerScrollerView.scrollEnabled = NO;
UIView *v1 = [UIView new];
v1.frame = CGRectMake(90, 0, 90, 90);
v1.backgroundColor = UIColor.yellowColor;
[self.inerScrollerView addSubview:v1];
UIView *v2 = [UIView new];
v2.frame = CGRectMake(90, 90, 90, 90);
v2.backgroundColor = UIColor.redColor;
[self.inerScrollerView addSubview:v2];
}
// 目标位置
CGFloat outContentOffsetY = 430;
CGFloat inerContentOffset2Y = 60;
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGPoint contentOffset = scrollView.contentOffset;
// NSLog(@"scrollViewDidScroll");
if (scrollView == self.outScrollerView && contentOffset.y >= outContentOffsetY) {
self.inerScrollerView.scrollEnabled = YES;
self.outScrollerView.scrollEnabled = NO;
// 外层滚动到目标位置后 把滚动距离 传给内存 scrollView
CGFloat offsetY = contentOffset.y - outContentOffsetY;
CGPoint contentOffset2 = self.inerScrollerView.contentOffset;
contentOffset2.y += offsetY;
[self.outScrollerView setContentOffset:CGPointMake(0, outContentOffsetY)];
[self.inerScrollerView setContentOffset:contentOffset2];
}
if (scrollView == self.inerScrollerView && contentOffset.y < inerContentOffset2Y) {
self.outScrollerView.scrollEnabled = YES;
self.inerScrollerView.scrollEnabled = NO;
// 内外层滚动到目标位置后 把滚动距离 传给外层 scrollView
CGFloat offsetY = contentOffset.y - inerContentOffset2Y;
CGPoint contentOffset1 = self.outScrollerView.contentOffset;
contentOffset1.y += offsetY;
[self.inerScrollerView setContentOffset:CGPointMake(0, inerContentOffset2Y)];
[self.outScrollerView setContentOffset:contentOffset1];
}
}
- (UIScrollView *)outScrollerView {
if (!_outScrollerView) {
_outScrollerView = [[UIScrollView alloc] init];
_outScrollerView.delegate = self;
_outScrollerView.backgroundColor = UIColor.blueColor;
}
return _outScrollerView;
}
- (UIScrollView *)inerScrollerView {
if (!_inerScrollerView) {
_inerScrollerView = [[UIScrollView alloc] init];
_inerScrollerView.delegate = self;
_inerScrollerView.backgroundColor = UIColor.grayColor;
}
return _inerScrollerView;
}
@end
#import "ScrollViewController.h"
@interface ScrollViewController ()<UIScrollViewDelegate>
@property(nonatomic, strong)UIScrollView *outScrollerView;
@property(nonatomic, strong)UIScrollView *inerScrollerView;
@end
@implementation ScrollViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.outScrollerView.frame = CGRectMake(10, 90, 300, 500);
self.outScrollerView.contentSize = CGSizeMake(300, 1800);
[self.view addSubview:self.outScrollerView];
self.inerScrollerView.frame = CGRectMake(10, 440, 240, 300);
self.inerScrollerView.contentSize = CGSizeMake(240, 800);
[self.outScrollerView addSubview:self.inerScrollerView];
self.inerScrollerView.scrollEnabled = NO;
UIView *v1 = [UIView new];
v1.frame = CGRectMake(90, 0, 90, 90);
v1.backgroundColor = UIColor.yellowColor;
[self.inerScrollerView addSubview:v1];
UIView *v2 = [UIView new];
v2.frame = CGRectMake(90, 90, 90, 90);
v2.backgroundColor = UIColor.redColor;
[self.inerScrollerView addSubview:v2];
}
// 目标位置
CGFloat outContentOffsetY = 430;
CGFloat inerContentOffset2Y = 60;
#pragma mark - UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
CGPoint contentOffset = scrollView.contentOffset;
// NSLog(@"scrollViewDidScroll");
if (scrollView == self.outScrollerView && contentOffset.y >= outContentOffsetY) {
self.inerScrollerView.scrollEnabled = YES;
self.outScrollerView.scrollEnabled = NO;
// 外层滚动到目标位置后 把滚动距离 传给内存 scrollView
CGFloat offsetY = contentOffset.y - outContentOffsetY;
CGPoint contentOffset2 = self.inerScrollerView.contentOffset;
contentOffset2.y += offsetY;
[self.outScrollerView setContentOffset:CGPointMake(0, outContentOffsetY)];
[self.inerScrollerView setContentOffset:contentOffset2];
}
if (scrollView == self.inerScrollerView && contentOffset.y < inerContentOffset2Y) {
self.outScrollerView.scrollEnabled = YES;
self.inerScrollerView.scrollEnabled = NO;
// 内外层滚动到目标位置后 把滚动距离 传给外层 scrollView
CGFloat offsetY = contentOffset.y - inerContentOffset2Y;
CGPoint contentOffset1 = self.outScrollerView.contentOffset;
contentOffset1.y += offsetY;
[self.inerScrollerView setContentOffset:CGPointMake(0, inerContentOffset2Y)];
[self.outScrollerView setContentOffset:contentOffset1];
}
}
- (UIScrollView *)outScrollerView {
if (!_outScrollerView) {
_outScrollerView = [[UIScrollView alloc] init];
_outScrollerView.delegate = self;
_outScrollerView.backgroundColor = UIColor.blueColor;
}
return _outScrollerView;
}
- (UIScrollView *)inerScrollerView {
if (!_inerScrollerView) {
_inerScrollerView = [[UIScrollView alloc] init];
_inerScrollerView.delegate = self;
_inerScrollerView.backgroundColor = UIColor.grayColor;
}
return _inerScrollerView;
}
@end
实现方式二:ScrollView嵌套二