UITabBarVC嵌套UISplitViewController:showDetail时如何无冗余代码隐藏TabBar?
解决UITabBar嵌套SplitView时showDetail隐藏TabBar的优雅方案
我之前也踩过这个坑——直接给详情页设置hidesBottomBarWhenPushed完全没效果,因为SplitViewController的showDetailViewController在不同设备上的行为不一样:iPhone上可能是push操作,但iPad上是直接替换详情容器,这时候hidesBottomBarWhenPushed的触发条件根本不满足。
下面给你两个不需要写冗余viewWillAppear的优雅方案:
方案一:自定义SplitViewController,自动处理隐藏逻辑
直接重写SplitViewController的showDetailViewController方法,每次展示新详情页时自动给目标VC设置隐藏TabBar的属性,一劳永逸:
class CustomSplitVC: UISplitViewController { override func showDetailViewController(_ vc: UIViewController, sender: Any?) { // 处理导航控制器包裹的情况 let targetVC = (vc as? UINavigationController)?.topViewController ?? vc targetVC.hidesBottomBarWhenPushed = true super.showDetailViewController(vc, sender: sender) } }
之后把项目里的SplitViewController换成这个自定义类就行,不管你调用多少次showDetailViewController,都会自动帮你隐藏TabBar,不需要在每个详情页里重复写代码。
方案二:通过KVO监听详情页变化,直接控制TabBar显隐
如果你的场景是iPad分屏模式(替换详情页而非push),上面的方案可能不生效,这时候可以用KVO监听SplitViewController的detailViewController属性变化,直接控制TabBar的显隐:
class CustomTabBarVC: UITabBarController { override func viewDidLoad() { super.viewDidLoad() // 给当前选中的SplitVC添加KVO监听 guard let splitVC = selectedViewController as? UISplitViewController else { return } splitVC.addObserver(self, forKeyPath: "detailViewController", options: [.new], context: nil) } override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) { guard keyPath == "detailViewController", let splitVC = object as? UISplitViewController else { super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context) return } // 这里判断当前详情页是否是初始的根详情页(比如RootDetailVC是你默认的详情页) let shouldHideTabBar = !(splitVC.detailViewController is RootDetailVC) tabBar.isHidden = shouldHideTabBar } deinit { // 记得移除监听,避免内存泄漏 guard let splitVC = selectedViewController as? UISplitViewController else { return } splitVC.removeObserver(self, forKeyPath: "detailViewController") } }
这个方案更灵活,你可以根据当前展示的详情页类型自由控制TabBar是否隐藏,完全不需要在详情页里写任何代码。
两种方案都能避免冗余的viewWillAppear代码,你可以根据自己的项目场景选一个就行~
内容的提问来源于stack exchange,提问作者Ihor M.
相关产品推荐
相关产品推荐

