iOS开发:从其他ViewController切回Tab时禁止TableView滚动至顶部
解决思路:区分「重复点击当前Tab」和「从其他Tab切换」场景
这个问题我做项目时也碰到过~核心问题就是你现在用的tabBarController(_:didSelect:)方法,不管是从其他Tab切换过来,还是用户重复点击当前已经选中的Tab项,都会触发。所以我们需要加一个判断,只在用户重复点击当前Tab时,才让TableView滚动到顶部,从其他Tab切回来时不执行这个操作。
下面给你两种可行的实现方案:
方案一:利用shouldSelect代理方法(推荐)
tabBarController(_:shouldSelect:)是在用户点击Tab项、还未完成切换前触发的,能精准判断是不是重复点击当前Tab。我们可以在这里拦截重复点击的操作,执行滚动逻辑:
func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { // 判断当前点击的是不是已经选中的Tab页 if viewController == tabBarController.selectedViewController { // 仅当选中的是第0个Tab时,执行滚动到顶部 if tabBarController.selectedIndex == 0 { // 根据你的页面结构获取对应的ViewController(如果是嵌套导航控制器的话要取topViewController) if let navVC = viewController as? UINavigationController, let targetVC = navVC.topViewController as? YourTableViewController { targetVC.tableView.setContentOffset(CGPoint.zero, animated: true) } else if let targetVC = viewController as? YourTableViewController { targetVC.tableView.setContentOffset(CGPoint.zero, animated: true) } } // 返回false,因为已经是当前选中的Tab,不需要执行切换操作 return false } // 其他情况正常切换Tab,返回true return true }
方案二:记录上一次选中的Tab索引
如果不想改动代理方法,也可以通过记录上一次的Tab索引来区分场景:
- 先在你的类中添加一个属性存储上一次选中的索引:
private var lastSelectedTabIndex = 0
- 修改原来的
didSelect方法:
func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { let currentTabIndex = tabBarController.selectedIndex // 只有当前点击的是已选中的第0个Tab时,才执行滚动 if currentTabIndex == 0 && currentTabIndex == lastSelectedTabIndex { self.tableView.setContentOffset(CGPoint.zero, animated: true) } // 更新上一次选中的索引 lastSelectedTabIndex = currentTabIndex }
两种方案都能实现你的需求,方案一的逻辑更清晰,也避免了不必要的Tab切换操作,更推荐使用~
内容的提问来源于stack exchange,提问作者Omid Kia
相关产品推荐
相关产品推荐

