iOS Swift中如何让MDCBottomSheet显示在底部导航栏(TabBarController)上方
我来帮你解决这个问题!你现在遇到的情况是MDCBottomSheet默认从屏幕最底部弹出,直接覆盖了底部导航栏,要让它显示在TabBar上方,核心是调整BottomSheet的展示层级和位置,下面给你两种可行的实现方案:
方案1:从TabBarController发起展示并调整安全区域
如果你的tabBar(_:didSelect:)方法是在UITabBarController的子类中实现的,可以用这种简单的方式调整:
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) { guard item.tag == 4 else { return } let vc = tempVC() let tabBarHeight = tabBar.frame.height // 让内容视图底部留出TabBar的高度,避免内容被遮挡 vc.additionalSafeAreaInsets.bottom = tabBarHeight // 禁止内容视图延伸到TabBar下方 vc.edgesForExtendedLayout = [] let bottomSheet = MDCBottomSheetController(contentViewController: vc) // 设置模态展示样式为覆盖当前上下文,保证TabBar始终可见 bottomSheet.modalPresentationStyle = .overCurrentContext // 可选:自定义BottomSheet的初始高度(比如占屏幕高度的60%) bottomSheet.preferredContentSize = CGSize(width: view.frame.width, height: view.frame.height - tabBarHeight - 20) present(bottomSheet, animated: true, completion: nil) }
如果你的tabBar(_:didSelect:)是在子ViewController中实现的,记得要从TabBarController发起present,而不是当前子VC:
// 子VC中的写法 override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) { if item.tag == 4 { let vc = tempVC() let bottomSheet = MDCBottomSheetController(contentViewController: vc) // 获取TabBarController实例来present tabBarController?.present(bottomSheet, animated: true) } }
方案2:将BottomSheet作为子视图添加到TabBarController
这种方式能完全精确控制BottomSheet的位置,适合需要高度定制动画的场景:
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) { guard item.tag == 4 else { return } let vc = tempVC() let bottomSheet = MDCBottomSheetController(contentViewController: vc) let tabBarHeight = tabBar.frame.height let desiredSheetHeight = view.frame.height * 0.6 // 自定义BottomSheet高度 // 将BottomSheet添加为TabBarController的子控制器 addChild(bottomSheet) view.addSubview(bottomSheet.view) bottomSheet.didMove(toParent: self) // 设置初始frame:让BottomSheet初始在TabBar上方的屏幕外 bottomSheet.view.frame = CGRect( x: 0, y: view.frame.height - tabBarHeight, width: view.frame.width, height: desiredSheetHeight ) bottomSheet.view.transform = CGAffineTransform(translationX: 0, y: desiredSheetHeight) // 添加滑入动画 UIView.animate(withDuration: 0.3) { bottomSheet.view.transform = .identity } // 给tempVC添加关闭逻辑(示例:点击视图关闭) let tapGesture = UITapGestureRecognizer(target: self, action: #selector(dismissBottomSheet)) vc.view.addGestureRecognizer(tapGesture) } @objc private func dismissBottomSheet() { guard let bottomSheet = children.first(where: { $0 is MDCBottomSheetController }) as? MDCBottomSheetController else { return } let sheetHeight = bottomSheet.view.frame.height UIView.animate(withDuration: 0.3, animations: { bottomSheet.view.transform = CGAffineTransform(translationX: 0, y: sheetHeight) }) { _ in bottomSheet.willMove(toParent: nil) bottomSheet.view.removeFromSuperview() bottomSheet.removeFromParent() } }
关键说明
- 方案1利用安全区域和模态展示样式,快速实现BottomSheet在TabBar上方的效果,代码简洁易维护;
- 方案2通过直接添加子视图的方式,能完全控制BottomSheet的弹出位置、动画和交互逻辑,适合复杂定制场景。
内容的提问来源于stack exchange,提问作者Sahil Parashar
相关产品推荐
相关产品推荐

