iOS点击按钮重设TabBar根控制器后选中项异常问题
问题根源
每次点击按钮时你都重新创建了一个全新的CustomTabBarViewController实例,全新的UITabBarController实例默认会选中第一个索引(即0位置的firstViewController),所以会出现自动跳回首页的现象。
之前在viewDidLoad中固定写死选中索引3的方案,会导致所有场景下初始化这个TabBar控制器都默认定位到最后一页,无法满足仅点击指定按钮时才触发选中最后一页的需求。
修复方案
方案1:必须重置根控制器的场景
如果你的业务逻辑要求点击按钮后必须重新设置App根控制器,不要把选中索引的逻辑硬编码在viewDidLoad中,通过新增可配置属性实现按需指定选中项:
- 给
CustomTabBarViewController新增可选配置项,用于接收外部传入的默认选中索引
class CustomTabBarViewController: UITabBarController { // 存储外部传入的默认选中索引,不传则走默认选中逻辑 var targetSelectedIndex: Int? override func viewDidLoad() { super.viewDidLoad() // 仅当外部传入了目标索引时,才执行选中操作 if let index = targetSelectedIndex { self.selectedIndex = index } } }
- 修改按钮点击事件的代码,初始化TabBar实例后传入目标索引,再设置为根控制器
let tabBarVC = UIStoryboard(name: "TabBarViewController", bundle: nil).instantiateViewController(withIdentifier: "CustomTabBarViewController") as! CustomTabBarViewController // 仅在当前点击场景下指定选中索引3 tabBarVC.targetSelectedIndex = 3 let nav = UINavigationController(rootViewController: tabBarVC) nav.setAsRoot()
方案2:仅需刷新当前页面内容的场景
如果点击按钮不需要重置整个App根控制器,只是要更新当前Tab页的内容,完全不需要重新创建新的TabBar实例,直接获取当前已加载的TabBar控制器操作即可,性能更好也不会出现选中项错乱的问题:
// 获取当前所在的TabBar控制器实例 guard let currentTabBarVC = self.tabBarController as? CustomTabBarViewController else { return } // 执行你需要的视图更新、数据刷新逻辑 // 刷新完成后手动指定选中索引 currentTabBarVC.selectedIndex = 3
优化建议
- 非必要不要频繁重建根TabBar控制器,重建会丢失所有Tab页的原有浏览状态、页面缓存,影响使用体验,能获取现有实例操作优先使用现有实例。
- 上述可配置索引的方式扩展性更强,后续如果其他场景需要默认选中第二个、第三个Tab页,只需要在初始化时给
targetSelectedIndex传入对应值即可,不需要修改控制器内部代码。
内容的提问来源于stack exchange,提问作者Mariam Sargsyan
相关产品推荐
相关产品推荐

