You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何检测点击TabBar切换控制器时ScrollView的滚动停止时机?

解决TabBar切换时UITableView滚动停止事件未触发的问题

当快速滑动UITableView的同时切换TabBarItem,当前ViewController的view会被移出视图层级,导致UIScrollView的三个停止代理方法都无法触发。可以通过以下几种方式处理:

方案1:监听TabBar切换通知

在包含UITableView的子ViewController中,监听TabBarController的切换通知,在切换时检查滚动状态:

- (void)viewDidLoad {
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self 
                                             selector:@selector(onTabBarSwitched:) 
                                                 name:UITabBarControllerDidSelectViewControllerNotification 
                                               object:nil];
}

- (void)onTabBarSwitched:(NSNotification *)note {
    UITabBarController *tabBarVC = (UITabBarController *)note.object;
    // 确认当前VC是被切换走的那个
    if (tabBarVC.selectedViewController != self) {
        [self handleScrollIfNeeded];
    }
}

- (void)handleScrollIfNeeded {
    if (self.tableView.isDragging || self.tableView.isDecelerating) {
        // 立即终止滚动
        [self.tableView setContentOffset:self.tableView.contentOffset animated:NO];
        // 执行滚动停止后的逻辑
        [self scrollViewStopped];
    }
}

- (void)scrollViewStopped {
    // 这里放原本在三个代理方法里的停止处理逻辑
}

- (void)dealloc {
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

方案2:利用ViewController生命周期方法

在子ViewController的viewWillDisappear:中检查滚动状态,因为切换TabBar时当前VC的view会进入消失流程:

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self handleScrollIfNeeded];
}

- (void)handleScrollIfNeeded {
    if (self.tableView.isDragging || self.tableView.isDecelerating) {
        [self.tableView setContentOffset:self.tableView.contentOffset animated:NO];
        [self scrollViewStopped];
    }
}

- (void)scrollViewStopped {
    // 统一的滚动停止处理逻辑
}

方案3:监听ScrollView的窗口移除事件

重写UIScrollView的代理方法scrollViewWillMoveToWindow:,当ScrollView即将从窗口移除时检查状态:

- (void)scrollViewWillMoveToWindow:(UIWindow *)newWindow {
    [super scrollViewWillMoveToWindow:newWindow];
    // 当scrollView即将离开窗口时
    if (newWindow == nil && (self.tableView.isDragging || self.tableView.isDecelerating)) {
        [self scrollViewStopped];
    }
}

注意事项

  • 将滚动停止的逻辑抽成公共方法scrollViewStopped,避免在多个地方重复代码,同时保证逻辑一致性。
  • 使用setContentOffset:animated:NO可以立即终止滚动,确保状态同步,避免后续出现异常。

内容的提问来源于stack exchange,提问作者ming

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 20:15:50