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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.29 20:22:42