效果圖

1,整體上是一個(gè)大的tableview,但是主要是下面的部分,如果第二部分不能左右滑動(dòng)的話,還是比較好實(shí)現(xiàn)的,在第二部分的區(qū)頭加3個(gè)按鈕,然后點(diǎn)擊切換不同的數(shù)據(jù)就行了,但是第二個(gè)區(qū)如果是3個(gè)不同的tableview的話,就是外部tableview上面再加tableview,那么上層tableview 就會(huì)攔截滑動(dòng)事件,導(dǎo)致下層的tableview 無法接受到事件了。
首先自定義一個(gè)tableview讓它實(shí)現(xiàn)下面這個(gè)方法,返回yes的話,那么它上層的tableview的滑動(dòng)事件它就能接收到了,
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
return YES;
}
2,第二重點(diǎn)就是:如果仔細(xì)觀察兩個(gè)tableview的滑動(dòng)事件的話,你就知道,外部的tableview滑動(dòng)的時(shí)候,內(nèi)嵌的tableview是不動(dòng)的,內(nèi)嵌的tableview滑動(dòng)的時(shí)候,外部的tabbleview是不動(dòng)的。因?yàn)閮?nèi)外兩個(gè)tableview都能響應(yīng)滑動(dòng)事件,所以要讓它們在不同情況下滑動(dòng),而兩者的切換時(shí)靠的通知,判斷條件就是自定義的3個(gè)切換按鈕部分是否接觸到導(dǎo)航條的位置。
外部tableview在創(chuàng)建的時(shí)候會(huì)注冊一個(gè)通知:
- (void)viewDidLoad {
[super viewDidLoad];
self.automaticallyAdjustsScrollViewInsets = NO;
[self.view addSubview:self.tableView];
self.title = @"商品詳情";
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(acceptNotify:) name:@"TheExternalScroll" object:nil];
}
接受到內(nèi)部tableview 發(fā)來的通知,判斷該不該滑動(dòng)。
-(void)acceptNotify:(NSNotification * )notify{
NSString * canScroll = notify.userInfo[@"canScroll"];
if ([canScroll isEqualToString:@"1"]) {
// 內(nèi)嵌scroll 通知 外部scroll可以滑動(dòng)了
_canScroll = YES;
}
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
CGFloat tabOffsetY = [self.tableView rectForSection:1].origin.y;
NSLog(@"tabOffsetY = %lf",tabOffsetY);
CGFloat offsetY = scrollView.contentOffset.y;
_scrollToBottom = _scrollToTop;
if (offsetY>=tabOffsetY) {
// 剛好第二部分的頂部接觸到導(dǎo)航條的地步了, 外部的table 固定偏移量,
scrollView.contentOffset = CGPointMake(0, tabOffsetY);
_scrollToTop = YES;
}else
{
_scrollToTop = NO;
}
if (_scrollToTop != _scrollToBottom) {
if (!_scrollToBottom && _scrollToTop) {
// 滑到頂部了,通知內(nèi)嵌table ,可以滑動(dòng)了,
[[NSNotificationCenter defaultCenter] postNotificationName:@"TheInsideScroll" object:nil userInfo:@{@"canScroll":@"1"}];
// 自己不能滑動(dòng)了
_canScroll = NO;
}
if (_scrollToBottom && !_scrollToTop) {
if (!_canScroll) {
scrollView.contentOffset = CGPointMake(0, tabOffsetY);
}
}
}
}
3,因?yàn)閮?nèi)嵌3個(gè)tableview,所以讓它們繼承同一個(gè)tableview,在根tableview,處理滑動(dòng)邏輯。
初始化的注冊兩個(gè)通知。
-(instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height) style:0];
self.tableView.delegate = self;
self.tableView.dataSource = self;
[self addSubview:self.tableView];
// 外部table 發(fā)來的通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(acceptNotihy:) name:@"TheInsideScroll" object:nil];
// 內(nèi)嵌的table 離開頂部時(shí)的通知
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(acceptNotihy:) name:@"TheExternalScroll" object:nil];
}
return self;
}
-(void)acceptNotihy:(NSNotification *)notify
{
if ([notify.name isEqualToString:@"TheInsideScroll"]) {
// 外部table 發(fā)來的通知
NSString * canScroll = notify.userInfo[@"canScroll"];
if ([canScroll isEqualToString:@"1"]) {
_canScroll = YES;
self.tableView.showsHorizontalScrollIndicator = YES;
}
}else if ([notify.name isEqualToString:@"TheExternalScroll"])
{
// 內(nèi)嵌table 發(fā)來的通知
self.tableView.contentOffset = CGPointZero;
_canScroll = NO;
self.tableView.showsHorizontalScrollIndicator = NO;
}
}
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
if (!_canScroll) {
[scrollView setContentOffset:CGPointZero];
}
CGFloat offsetY = scrollView.contentOffset.y;
if (offsetY<0) {
// 內(nèi)嵌的table到頂了;通知外面的table滑動(dòng);
[[NSNotificationCenter defaultCenter] postNotificationName:@"TheExternalScroll" object:nil userInfo:@{@"canScroll":@"1"}];
}
}
這種布局模式好多APP里面都會(huì)有,還有滑動(dòng)時(shí)候?qū)Ш綏l透明效果,其實(shí)微博的個(gè)人主頁也可以這么實(shí)現(xiàn)。
Demo地址:https://github.com/zdq1179169386/-Demo;
另外淘寶的分屏顯示的,
Demo:https://github.com/zdq1179169386/taobaoProductDetail