iOS 13中UITabBar.ItemPositioning失效,如何让两个TabBar项靠近显示?
解决iOS13+ UITabBar两个Item紧密居中显示的问题
这个问题我之前适配iOS13的时候也踩过坑!原来的UITabBar.ItemPositioning确实被苹果标为「旧版自定义」API了,在iOS13之后单独使用它不再生效。想要实现两个tabBarItem紧密居中排列,得用iOS13引入的新布局配置方式,下面给你两种可行方案:
方案一:直接设置TabBar的itemSpacing和itemWidth
这种方式比较简洁,不需要用到新的外观类,兼容iOS13+:
override func viewDidLoad() { super.viewDidLoad() // 保留centered定位,配合下面的属性生效 tabBar.itemPositioning = .centered // 设置两个item之间的间距为0,让它们紧密挨在一起 tabBar.itemSpacing = 0 // 计算item宽度:屏幕宽度减去安全区左右边距后,每个item占40%(可以根据需求调整比例) let safeAreaInsets = tabBar.safeAreaInsets let availableWidth = UIScreen.main.bounds.width - safeAreaInsets.left - safeAreaInsets.right tabBar.itemWidth = availableWidth * 0.4 }
原理是iOS13之后,itemSpacing和itemWidth的优先级高于旧的itemPositioning,结合.centered就能让两个item紧密居中显示。
方案二:使用UITabBarAppearance(iOS13+推荐)
苹果在iOS13引入了UITabBarAppearance,用来更精细化地自定义tabBar样式,这也是官方推荐的方式:
override func viewDidLoad() { super.viewDidLoad() if #available(iOS 13.0, *) { let tabBarAppearance = UITabBarAppearance() // 配置堆叠布局下的item间距和宽度 let itemAppearance = tabBarAppearance.stackedLayoutAppearance itemAppearance.itemSpacing = 0 let safeAreaInsets = tabBar.safeAreaInsets let availableWidth = UIScreen.main.bounds.width - safeAreaInsets.left - safeAreaInsets.right itemAppearance.normal.width = availableWidth * 0.4 // 将配置应用到tabBar tabBar.standardAppearance = tabBarAppearance // 如果需要支持页面滚动到顶部时的tabBar样式,同步设置scrollEdgeAppearance tabBar.scrollEdgeAppearance = tabBarAppearance } else { // iOS12及以下沿用原来的方法 tabBar.itemPositioning = .centered } }
这种方式的好处是可以分别配置不同状态下的tabBar样式(比如选中、未选中、堆叠/内联/滚动布局),扩展性更强。
注意事项
- 计算item宽度时记得考虑tabBar的安全区边距,尤其是在有刘海的设备上,避免item被安全区截断或者间距异常。
- 如果你不需要固定item宽度,也可以尝试设置
tabBar.itemWidth = UITabBar.automaticDimension,配合itemSpacing = 0,让系统自动计算合适的宽度,但固定宽度的方式更可控。
内容的提问来源于stack exchange,提问作者jamix
相关产品推荐
相关产品推荐

