iOS13 iPad端修改UITabBar宽度失效问题求助
嘿,我之前也踩过iOS13 iPad上修改TabBar宽度的坑!苹果在iOS13之后对UITabBar的布局逻辑做了大调整,直接改frame或者瞎用sizeThatFits肯定不好使,给你几个亲测有效的解决办法:
方法一:用Auto Layout约束+UITabBarAppearance(最推荐)
iOS13之后系统会给TabBar自动添加一套约束,直接修改frame会被系统的约束强制重置,所以我们要手动接管约束,同时用新的UITabBarAppearance来配置样式(避免样式错乱)。
override func viewWillLayoutSubviews() { super.viewWillLayoutSubviews() // 针对iOS13+配置TabBar外观(按需调整样式) if #available(iOS 13.0, *) { let tabBarAppearance = UITabBarAppearance() tabBarAppearance.backgroundColor = .white // 示例:设置背景色 tabBarAppearance.shadowColor = .lightGray // 示例:设置阴影 tabBar.standardAppearance = tabBarAppearance tabBar.scrollEdgeAppearance = tabBarAppearance // 适配滚动到顶部的样式 } // 关闭TabBar的自动约束转换,手动添加约束 tabBar.translatesAutoresizingMaskIntoConstraints = false NSLayoutConstraint.activate([ // 左右各留210间距,总宽度就是view宽度-420 tabBar.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 210), tabBar.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -210), tabBar.bottomAnchor.constraint(equalTo: view.bottomAnchor), // 保持TabBar原有高度,也可以手动设置固定值比如49 tabBar.heightAnchor.constraint(equalToConstant: tabBar.frame.height) ]) }
这个方法的好处是完全贴合Auto Layout的逻辑,不会和系统布局冲突,在iPad和iPhone上都能稳定运行。
方法二:自定义TabBarController的layoutSubviews
如果你用的是自定义TabBarController,可以重写它的layoutSubviews方法,在系统布局完成后手动调整TabBar的frame,同时别忘了调整内部item的位置:
class CustomTabBarController: UITabBarController { override func layoutSubviews() { super.layoutSubviews() guard let tabBar = self.tabBar else { return } // 计算新的frame:宽度减420,居中显示 var newFrame = tabBar.frame newFrame.size.width = view.bounds.width - 420 newFrame.origin.x = (view.bounds.width - newFrame.size.width) / 2 tabBar.frame = newFrame // 手动调整TabBar内部的item位置(不然item会留在原位置) let itemWidth = newFrame.width / CGFloat(tabBar.items?.count ?? 0) tabBar.subviews.forEach { subview in // 筛选出TabBarItem对应的控件 if subview is UIControl && subview.tag != 0 { let index = subview.tag - 1 subview.frame = CGRect( x: CGFloat(index) * itemWidth, y: subview.frame.origin.y, width: itemWidth, height: subview.frame.height ) } } } }
不过这个方法有点“硬编码”的感觉,需要手动处理item的布局,不如第一种方法优雅,适合临时救急。
方法三:正确自定义TabBar的sizeThatFits+intrinsicContentSize
你之前说sizeThatFits只能改高度,是因为系统默认忽略了宽度的修改。如果要自定义TabBar的宽度,得结合intrinsicContentSize和Auto Layout约束一起用:
首先自定义TabBar:
class CustomTabBar: UITabBar { // 自定义固有内容大小 override var intrinsicContentSize: CGSize { let originalSize = super.intrinsicContentSize return CGSize(width: UIScreen.main.bounds.width - 420, height: originalSize.height) } // 重写sizeThatFits返回自定义宽度 override func sizeThatFits(_ size: CGSize) -> CGSize { let fitSize = super.sizeThatFits(size) return CGSize(width: UIScreen.main.bounds.width - 420, height: fitSize.height) } }
然后在TabBarController里替换默认TabBar并添加约束:
class CustomTabBarController: UITabBarController { override func viewDidLoad() { super.viewDidLoad() let customTabBar = CustomTabBar() customTabBar.translatesAutoresizingMaskIntoConstraints = false // 通过KVC替换默认的tabBar setValue(customTabBar, forKey: "tabBar") // 添加约束确保TabBar居中且宽度符合要求 NSLayoutConstraint.activate([ customTabBar.centerXAnchor.constraint(equalTo: view.centerXAnchor), customTabBar.bottomAnchor.constraint(equalTo: view.bottomAnchor), customTabBar.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width - 420), customTabBar.heightAnchor.constraint(equalToConstant: 49) // 默认TabBar高度 ]) } }
这个方法适合需要高度自定义TabBar样式的场景,但需要注意适配不同屏幕尺寸。
内容的提问来源于stack exchange,提问作者Mohammad Yeganeh
相关产品推荐
相关产品推荐

