嵌套滾動的機制
目前的結構是這樣的,整個頁面是一個大的tableView,
Cell 是整個頁面的大小,cell 中嵌套了一個tableView
通過測試我們發現滾動的時候,系統的機制是這樣的,
我們滑動內部小的tableView, 開始滑動的時候,如果內部小tableview沒有滑到最大偏移量(contentSize.height - bounds.size.height)
我們滑動
內部小的tableView的時候, 如果該方向上外層tableView沒有滾動到
最后一個(向上滾動的時候是第一個), 則內部tableView滾動到最大偏移量的時候直接帶動外層
tableView滾動,如果外城是pagingEnabeled 的話,則外層的展示一個彈性效果,
如果內部的滾動到邊界的時候,外層的tableView已經滾動到頭了,則內部的tableView
展示一個彈性效果。
如果我們開始滑動內部小的tableView的時候,tableView在該方向上已經滾動到頭了,則直接執行外層tableView的滾動,
如果外層在該方向上沒有到頭,則滾動外層tableView, 如果外層tableView在該方向上已經滾動到頭了,則外層tableView
展示一個彈性效果
這個時候就有一個問題,就是正常的情況下,如果我們滑動內部 小的tableView, 如果開始滑動的時候, 內部的tableView 沒有滾動
到盡頭,我們滑動其滾動到盡頭的時候,根據上面的機制,就會帶動外層的tableView滾動,這是我們不想看到的,
所以我們可以這樣, 內部的tableView沒有滾動到盡頭的時候,開始拖動這個時候,會執行內層的begindragging, 如果,
開始拖動的時候,內部的tableView已經滾動到盡頭了,則會直接執行外層begindragging, 由此,我們可以
在內層tableView 的 begingdragging 代理方法開始執行的時候,禁止外層的tableView滾動,在內層的停止滾動之后,
再允許外層的滾動
這個效果圖是自然狀態下的效果
這個效果是經過我們處理之后的效果,滑動內部的時候,不會
引起外層的滾動
//
// LBDouyinCell.m
// TEXT
//
// Created by mac on 2024/7/7.
// Copyright ? 2024 劉博. All rights reserved.
//#import "LBDouyinCell.h"@interface LBDouyinCell () <UITableViewDelegate, UITableViewDataSource>@property (nonatomic, strong) UITableView *commentTableView;@property (nonatomic, strong) UILabel *titleLabel;@end@implementation LBDouyinCell- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {[self setUpUI];}return self;
}- (void)setUpUI
{[self.contentView addSubview:self.commentTableView];[self.contentView addSubview:self.titleLabel];[self.commentTableView reloadData];
}- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{self.parentTableView.scrollEnabled = NO;NSLog(@"阿哈哈哈內層的內層的scrollViewWillBeginDragging");;
}- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{NSLog(@"哈哈哈哈哈內層的內層的scrollViewDidScroll");
}- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{self.parentTableView.scrollEnabled = YES;
}- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{if (!decelerate) {//self.parentTableView.scrollEnabled = YES;}
}#pragma mark - UITableViewDelegate, UITableViewDataSource- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{return 5;
}- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{return 60;
}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([UITableViewCell class])];cell.textLabel.text = [NSString stringWithFormat:@"哈哈哈這里是第%ld條", indexPath.row];return cell;
}- (void)updateWithTitle:(NSString *)title
{self.titleLabel.text= title;
}#pragma mark - lazy load- (UILabel *)titleLabel
{if (!_titleLabel) {_titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 100, 200, 50)];_titleLabel.backgroundColor = [UIColor magentaColor];_titleLabel.text = @"我是標題";}return _titleLabel;
}- (UITableView *)commentTableView
{if (!_commentTableView) {_commentTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 400, 200, 200) style:UITableViewStylePlain];_commentTableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;[_commentTableView registerClass:[UITableViewCell class] forCellReuseIdentifier:NSStringFromClass([UITableViewCell class])];_commentTableView.delegate = self;_commentTableView.dataSource = self;}return _commentTableView;
}/*
#pragma mark - Navigation// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {// Get the new view controller using [segue destinationViewController].// Pass the selected object to the new view controller.
}
*/@end
這里demo link