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

如何在iPhone X横屏时强制UITabBar使用紧凑样式?

iPhone X横屏UITabBar图标布局异常的解决方案

我之前在做自定义UITabBar适配的时候,也碰到过和你一模一样的问题——毕竟UITabBarController内部有一套系统默认的适配逻辑,单独使用UITabBar时这套逻辑不会自动触发。结合你已经做的安全区域设置和容器视图调整,给你几个亲测有效的解决方案:

1. 监听设备旋转,手动调整Item布局

通过监听设备旋转事件,在横屏时针对iPhone X系列设备单独调整tabBar的item间距、图标内边距等属性,让布局恢复正常:

override func viewDidLoad() {
    super.viewDidLoad()
    // 添加旋转监听通知
    NotificationCenter.default.addObserver(self, selector: #selector(handleScreenRotation), name: UIDevice.orientationDidChangeNotification, object: nil)
}

@objc private func handleScreenRotation() {
    guard let tabBar = self.customTabBar else { return }
    
    let isLandscape = UIDevice.current.orientation.isLandscape
    let isIPhoneXSeries = UIDevice.current.userInterfaceIdiom == .phone && UIScreen.main.nativeBounds.height >= 2436
    
    if isLandscape && isIPhoneXSeries {
        // 横屏适配:调整item间距和图标内边距
        tabBar.itemSpacing = 18 // 可根据实际需求修改
        tabBar.items?.forEach { item in
            item.imageInsets = UIEdgeInsets(top: 6, left: 0, bottom: -6, right: 0)
        }
    } else {
        // 恢复竖屏/非X设备的默认布局
        tabBar.itemSpacing = 0
        tabBar.items?.forEach { item in
            item.imageInsets = .zero
        }
    }
}

deinit {
    // 记得移除通知,避免内存泄漏
    NotificationCenter.default.removeObserver(self)
}

2. 自定义UITabBar子类,重写布局逻辑

通过自定义UITabBar子类,在layoutSubviews方法中模拟UITabBarController的横屏布局逻辑,强制让item均匀分布在安全区域内:

class AdaptiveTabBar: UITabBar {
    override func layoutSubviews() {
        super.layoutSubviews()
        
        let isLandscape = UIDevice.current.orientation.isLandscape
        let isIPhoneXSeries = UIDevice.current.userInterfaceIdiom == .phone && UIScreen.main.nativeBounds.height >= 2436
        
        guard isLandscape && isIPhoneXSeries else {
            // 非目标场景,使用系统默认布局
            super.layoutSubviews()
            return
        }
        
        // 获取横屏时的安全区域左右留白(对应刘海和底部指示条区域)
        let safeInset = self.safeAreaInsets
        let availableWidth = self.bounds.width - safeInset.left - safeInset.right
        let itemCount = self.items?.count ?? 0
        
        guard itemCount > 0 else { return }
        
        // 计算每个item的宽度
        let itemWidth = availableWidth / CGFloat(itemCount)
        // 遍历调整每个tabBarItem的视图布局
        self.subviews.forEach { subview in
            // 识别UITabBarButton(系统内部的item视图类)
            if NSStringFromClass(subview.classForCoder) == "UITabBarButton" {
                let index = subview.tag // 系统默认会给tabBarButton设置对应item的索引tag
                subview.frame = CGRect(
                    x: safeInset.left + itemWidth * CGFloat(index),
                    y: subview.frame.origin.y,
                    width: itemWidth,
                    height: subview.frame.height
                )
            }
        }
    }
}

使用时直接把你的UITabBar替换成这个自定义类即可,它会自动处理横屏时的布局适配。

3. 优先考虑使用UITabBarController(如果场景允许)

如果你的业务场景没有强需求必须单独使用UITabBar,最省心的方式还是直接用UITabBarController来管理标签栏——系统已经帮我们处理了所有设备(包括iPhone X横屏)的适配逻辑,不需要额外写适配代码。

额外注意点

  • 确保你的UITabBar容器视图已经正确绑定了safeAreaLayoutGuide的约束,避免出现错位问题;
  • 测试时覆盖iPhone X系列的所有机型(X、XS、XR、11及后续刘海屏机型),因为不同机型的安全区域Insets可能略有差异。

内容的提问来源于stack exchange,提问作者Nathan Barreto

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:43:14