如何将UITabBarItem中的图片与标题文本独立定位?
解决UITabBarItem选中文本加粗导致图片偏移的问题
嘿,这个场景我太熟了!默认UITabBarItem的布局逻辑是把图片和标题当成一个整体来排版,文本加粗后宽度变大,就会拉扯着图片一起偏移,确实挺烦的。要让这两个元素定位完全独立,最靠谱的是自定义UITabBarItem的内容视图,让我们完全掌控它们的布局约束,下面给你详细说两种方案:
方案一:自定义TabBarItem视图(推荐,稳定可控)
直接抛弃系统默认的UITabBarItem布局,自己创建一个包含图片和标签的UIView,把它设置为UITabBarItem的customView。这样图片和标签的约束都由我们定义,文本怎么变都不会影响图片位置。
第一步:创建自定义视图类
class CustomTabBarItemView: UIView { private let iconImageView = UIImageView() private let titleLabel = UILabel() // 初始化方法 override init(frame: CGRect) { super.init(frame: frame) setupSubviewsAndConstraints() } required init?(coder: NSCoder) { super.init(coder: coder) setupSubviewsAndConstraints() } // 配置子视图和约束 private func setupSubviewsAndConstraints() { // 配置图片视图 iconImageView.contentMode = .scaleAspectFit iconImageView.translatesAutoresizingMaskIntoConstraints = false addSubview(iconImageView) // 配置标题标签 titleLabel.textAlignment = .center titleLabel.font = UIFont.systemFont(ofSize: 10) titleLabel.translatesAutoresizingMaskIntoConstraints = false addSubview(titleLabel) // 设置核心约束:图片和标签都绑定到父视图的中心X,互相之间只保留固定间距 NSLayoutConstraint.activate([ // 图片居中,底部和标签顶部间距固定 iconImageView.centerXAnchor.constraint(equalTo: self.centerXAnchor), iconImageView.bottomAnchor.constraint(equalTo: titleLabel.topAnchor, constant: -4), iconImageView.widthAnchor.constraint(equalToConstant: 24), iconImageView.heightAnchor.constraint(equalToConstant: 24), // 标签居中,底部贴父视图底部 titleLabel.centerXAnchor.constraint(equalTo: self.centerXAnchor), titleLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor, constant: -2) ]) } // 对外暴露配置方法,设置图片、标题和选中状态 func setup(with image: UIImage?, title: String?, isSelected: Bool) { iconImageView.image = image?.withRenderingMode(.alwaysTemplate) titleLabel.text = title // 选中时加粗文本,同时调整颜色 let selectedTint = UIColor.systemBlue let normalTint = UIColor.gray titleLabel.font = isSelected ? UIFont.boldSystemFont(ofSize: 10) : UIFont.systemFont(ofSize: 10) iconImageView.tintColor = isSelected ? selectedTint : normalTint titleLabel.textColor = isSelected ? selectedTint : normalTint } }
第二步:在TabBarController中使用自定义视图
class MainTabBarController: UITabBarController { override func viewDidLoad() { super.viewDidLoad() setupTabBarItems() // 监听tab选中事件,更新视图状态 self.delegate = self } private func setupTabBarItems() { // 示例:创建第一个Tab的视图控制器和自定义TabItem let homeVC = HomeViewController() let homeTabView = CustomTabBarItemView() homeTabView.setup(with: UIImage(named: "home_icon"), title: "首页", isSelected: true) homeVC.tabBarItem.customView = homeTabView // 重复上述步骤创建其他4个Tab... let discoverVC = DiscoverViewController() let discoverTabView = CustomTabBarItemView() discoverTabView.setup(with: UIImage(named: "discover_icon"), title: "发现", isSelected: false) discoverVC.tabBarItem.customView = discoverTabView // 把所有VC添加到TabBarController self.viewControllers = [homeVC, discoverVC, /* 剩下3个VC */] } } // 实现TabBarControllerDelegate,处理选中状态切换 extension MainTabBarController: UITabBarControllerDelegate { func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { guard let tabItems = tabBarController.tabBar.items else { return } // 遍历所有TabItem,更新自定义视图的选中状态 for (index, item) in tabItems.enumerated() { guard let customTabView = item.customView as? CustomTabBarItemView else { continue } let isSelected = index == tabBarController.selectedIndex customTabView.setup(with: item.image, title: item.title, isSelected: isSelected) } } }
这样设置后,不管标题是否加粗,图片始终保持在父视图的中心位置,完全不受文本宽度变化的影响。
方案二:修改系统UITabBarItem内部约束(hack方式,不推荐)
如果你不想自定义视图,也可以通过KVC获取系统UITabBarItem内部的图片和标签视图,强制修改它们的约束,让两者都绑定到父视图中心。不过这个方法依赖苹果的私有API结构,后续系统更新可能失效,谨慎使用:
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) for item in tabBar.items ?? [] { guard let containerView = item.value(forKey: "view") as? UIView else { continue } for subview in containerView.subviews { if subview is UIImageView { // 固定图片的中心X约束 subview.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true } else if subview is UILabel { // 固定标签的中心X约束 subview.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true } } } }
总结
优先选择自定义视图方案,它不仅解决了图片偏移的问题,还能让你完全自定义TabBarItem的样式(比如调整图片大小、文本字号、间距等),扩展性极强,而且完全符合苹果的开发规范,不会有后续版本兼容问题。
内容的提问来源于stack exchange,提问作者spencer
相关产品推荐
相关产品推荐

