iOS ScrollView嵌套多個TableView

經常會遇到嵌套多個TableView的需求。以下是我最初的想法,但是不靈活,有侷限。

存在的問題,如果底部分類數據爲空時,不顯示底部的視圖,滑動邏輯則需變動。

佈局分析:

效果如下:

ScrollView可同時執行多種手勢

@implementation FLYBaseScrollView

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    return YES;
}

添加ScrollView 再添加TopView BottomView

    [self.view addSubview:self.baseScrollView];
    self.topView = [[FLYTopView alloc] init];
    self.topView.frame = CGRectMake(0, 0, SCREEN_WIDTH, self.screen_height);
    [self.topView renderUIWithInfo:@[] Model:@{}];
    [self.baseScrollView addSubview:self.topView];
    
    CGFloat contentSizeheight = self.topView.contentSizeHeight;
    if (contentSizeheight > self.screen_height) {
        self.baseScrollView.contentSize = CGSizeMake(SCREEN_WIDTH, self.screen_height*2);
        FLYBottomView *view = [[FLYBottomView alloc] initWithFrame:CGRectMake(0, self.screen_height, SCREEN_WIDTH, self.screen_height) ConfigArray:self.dataSource];
        [self.baseScrollView addSubview:view];
    } else {
        self.baseScrollView.contentSize = CGSizeMake(SCREEN_WIDTH, contentSizeheight + self.screen_height);
        FLYBottomView *view = [[FLYBottomView alloc] initWithFrame:CGRectMake(0, contentSizeheight, SCREEN_WIDTH, self.screen_height) ConfigArray:self.dataSource];
        [self.baseScrollView addSubview:view];
    }

FLYBaseScrollView   scrollViewDidScroll

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat tabOffsetY;
    CGFloat offsetY = scrollView.contentOffset.y;
    
    _isTopIsCanNotMoveTabViewPre = _isTopIsCanNotMoveTabView;
    _isCanMoveTopTabViewPre = _isCanMoveTopTabView;
    
    if (self.topView.contentSizeHeight > self.screen_height) {
        tabOffsetY = self.screen_height;
    } else {
        tabOffsetY = self.topView.contentSizeHeight;
        _isCanMoveTopTabView = NO;
    }
    
    if (offsetY >= tabOffsetY) {
        scrollView.contentOffset = CGPointMake(0, tabOffsetY);
        _isTopIsCanNotMoveTabView = YES;
        _isCanMoveTopTabView = NO;
    } else {
        _isTopIsCanNotMoveTabView = NO;
        int temp = self.topView.contentSizeHeight-self.screen_height;
        if (temp > 0) {
            if (self.topView.contentOffsetY >= temp) {
                if (offsetY <= 0) {
                    scrollView.contentOffset = CGPointMake(0, 0);
                    _isCanMoveTopTabView = YES;
                } else {
                    _isCanMoveTopTabView = NO;
                }
            } else if (self.topView.contentOffsetY == 0) {
                if (offsetY > 0) {
                    _isCanMoveTopTabView = YES;
                } else {
                    _isCanMoveTopTabView = NO;
                }
            }
            else {
                scrollView.contentOffset = CGPointMake(0, 0);
                _isCanMoveTopTabView = YES;
            }
        }
    }
    
    
    if (_isCanMoveTopTabView != _isCanMoveTopTabViewPre) {
        if (!_isCanMoveTopTabViewPre && _isCanMoveTopTabView) {
            [[NSNotificationCenter defaultCenter] postNotificationName:@"leaveHeaderBottom" object:nil userInfo:@{@"canScroll":@"1"}];
            _canScroll = NO;
            
        }
        if(_isCanMoveTopTabViewPre && !_isCanMoveTopTabView) {
            if (!_canScroll) {
            }
        }
    }
    
    
    if (_isTopIsCanNotMoveTabView != _isTopIsCanNotMoveTabViewPre) {
        if (!_isTopIsCanNotMoveTabViewPre && _isTopIsCanNotMoveTabView) {
            //NSLog(@"滑動到頂端");
            [[NSNotificationCenter defaultCenter] postNotificationName:@"goTop" object:nil userInfo:@{@"canScroll":@"1"}];
            _canScroll = NO;
        }
        if(_isTopIsCanNotMoveTabViewPre && !_isTopIsCanNotMoveTabView){
            //NSLog(@"離開頂端");
            if (!_canScroll) {
                scrollView.contentOffset = CGPointMake(0, tabOffsetY);
            }
        }
    }
}

FLYTopView scrollViewDidScroll

- (void)acceptMsg:(NSNotification *)notification {
    NSString *notificationName = notification.name;
    if ([notificationName isEqualToString:@"goBottom"]) {
        int temp = self.contentSizeHeight-self.bounds.size.height;
        self.mTableView.contentOffset = CGPointMake(0, temp);
        self.canScroll = NO;
    }
    else if([notificationName isEqualToString:@"leaveHeaderBottom"]){
        NSDictionary *userInfo = notification.userInfo;
        NSString *canScroll = userInfo[@"canScroll"];
        if ([canScroll isEqualToString:@"1"]) {
            self.canScroll = YES;
        }
    }
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat offsetY = scrollView.contentOffset.y;
    int temp = self.contentSizeHeight-self.bounds.size.height;
    if (!self.canScroll) {
        if (offsetY >= 0) {
            [scrollView setContentOffset:CGPointMake(0, temp)];
        }
    }

    if (offsetY >= temp) {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"goBottom" object:nil userInfo:@{@"canScroll":@"1"}];
    }
}

FLYBottomView->FLYGroupsItemView scrollViewDidScroll

- (void)acceptMsg:(NSNotification *)notification {
    NSString *notificationName = notification.name;
    if ([notificationName isEqualToString:@"goTop"]) {
        NSDictionary *userInfo = notification.userInfo;
        NSString *canScroll = userInfo[@"canScroll"];
        if ([canScroll isEqualToString:@"1"]) {
            self.canScroll = YES;
        }
    }else if([notificationName isEqualToString:@"leaveTop"]){
        self.mTableView.contentOffset = CGPointZero;
        self.canScroll = NO;
    }
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView{
    if (!self.canScroll) {
        [scrollView setContentOffset:CGPointZero];
    }
    CGFloat offsetY = scrollView.contentOffset.y;
    if (offsetY<=0) {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"leaveTop" object:nil userInfo:@{@"canScroll":@"1"}];
    }
}

Github下載地址:https://github.com/superman-fly/FLYNestTableView

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章