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

如何调整UITabBar Item的图片与文字位置?自定义TabBar配置求助

自定义TabBar Item图文位置调整问题

问题描述

我自定义了TabBar,但无法修改TabBar Item内部的图片与文字位置,当前效果和期望效果如下:

当前效果:
当前TabBar展示效果

期望效果:
期望TabBar展示效果

相关代码如下:

TabBar Item初始化代码

private func initializeTabBar() {
    let mainNavigationController = MainNavigationController()
    mainNavigationController.tabBarItem = UITabBarItem(title: "Explorer", image: UIImage(named: "dot"), tag: 0)
 
    let mainCoordinator = coordinatorFactory.makeMainCoordinator(with: Router(rootController: mainNavigationController))
    
    let BasketViewController = BusketViewController()
    BasketViewController.tabBarItem = UITabBarItem(title: "", image: UIImage(named: "busket"), tag: 1)

    let FavoriteViewController = FavoriteViewController()
    FavoriteViewController.tabBarItem = UITabBarItem(title: "", image: UIImage(named: "heart"), tag: 2)
    
    let ProfileViewController = ProfileViewController()
    ProfileViewController.tabBarItem = UITabBarItem(title: "", image: UIImage(named: "profile"), tag: 3)
    
    tabBarController.viewControllers = [mainNavigationController,BasketViewController,FavoriteViewController,ProfileViewController]
}

TabBar配置代码

func setup() {
    tabBar.itemWidth = tabBar.bounds.width / 10
    tabBar.itemPositioning = .centered
    
    tabBar.tintColor = AppColors.white
    tabBar.unselectedItemTintColor = AppColors.white
}

func setupBackground() {
    let positionX: CGFloat = 0
    let PositionY: CGFloat = 8
    let width = tabBar.bounds.width - positionX * 2
    let height = tabBar.bounds.height + PositionY * 2
    let rounderLayer = CAShapeLayer()
    let bezierPath = UIBezierPath(
        roundedRect: CGRect(x: positionX, y: tabBar.bounds.minY - PositionY, width: width, height: height), cornerRadius: height / 2 )
    rounderLayer.path = bezierPath.cgPath
    rounderLayer.fillColor = AppColors.darkBlue.cgColor
    tabBar.layer.insertSublayer(rounderLayer, at: 0)
}

解决方案

方案1:给目标Item设置自定义视图

直接给第一个TabBarItem创建自定义视图,手动布局图片和文字的位置,这种方式简单直接,适合只调整单个Item的场景:

// 在initializeTabBar方法中,替换第一个item的初始化代码
let mainNavigationController = MainNavigationController()

// 创建自定义Item视图
let customItemView = UIView(frame: CGRect(x: 0, y: 0, width: 90, height: tabBarController.tabBar.bounds.height))

// 图片视图
let iconView = UIImageView(image: UIImage(named: "dot"))
iconView.tintColor = AppColors.white
iconView.frame = CGRect(x: 0, y: (customItemView.bounds.height - 20)/2, width: 20, height: 20)

// 文字标签
let titleLabel = UILabel()
titleLabel.text = "Explorer"
titleLabel.textColor = AppColors.white
titleLabel.font = UIFont.systemFont(ofSize: 14)
titleLabel.sizeToFit()
titleLabel.frame = CGRect(x: iconView.frame.maxX + 8, y: (customItemView.bounds.height - titleLabel.bounds.height)/2, width: titleLabel.bounds.width, height: titleLabel.bounds.height)

// 添加子视图
customItemView.addSubview(iconView)
customItemView.addSubview(titleLabel)

// 绑定到TabBarItem
mainNavigationController.tabBarItem.customView = customItemView

注意:如果需要处理选中/未选中的样式切换,可以监听TabBar的selectedItem变化,更新自定义视图的图片和文字颜色。

方案2:自定义UITabBar全局控制布局

如果需要更统一的布局管理,或者后续有更多Item需要调整,可以自定义UITabBar,重写layoutSubviews方法来调整内部元素位置:

class CustomTabBar: UITabBar {
    override func layoutSubviews() {
        super.layoutSubviews()
        
        // 遍历所有TabBar按钮
        for subview in subviews where subview is UIControl {
            guard let tabItem = (subview as? UIControl)?.value(forKey: "_item") as? UITabBarItem else { continue }
            
            // 处理第一个Item(tag=0)
            if tabItem.tag == 0 {
                // 找到内部的图片和标签
                var iconView: UIImageView?
                var titleLabel: UILabel?
                
                for sub in subview.subviews {
                    if let iv = sub as? UIImageView {
                        iconView = iv
                    } else if let lb = sub as? UILabel {
                        titleLabel = lb
                    }
                }
                
                guard let iv = iconView, let lb = titleLabel else { continue }
                
                // 调整布局:图片左,文字右,垂直居中
                iv.frame = CGRect(x: 0, y: (subview.bounds.height - iv.bounds.height)/2, width: iv.bounds.width, height: iv.bounds.height)
                lb.frame = CGRect(x: iv.frame.maxX + 8, y: (subview.bounds.height - lb.bounds.height)/2, width: lb.bounds.width, height: lb.bounds.height)
                
                // 调整按钮宽度适配内容
                subview.frame = CGRect(x: subview.frame.origin.x, y: subview.frame.origin.y, width: iv.frame.maxX + 8 + lb.bounds.width, height: subview.bounds.height)
            } else {
                // 其他无标题Item,让图片居中
                if let iconView = subview.subviews.first(where: { $0 is UIImageView }) as? UIImageView {
                    iconView.center = subview.center
                }
            }
        }
    }
}

然后替换原有的TabBar:

// 在TabBar配置前,设置自定义TabBar
tabBarController.tabBar = CustomTabBar()
// 再执行原有的setup和setupBackground方法
setup()
setupBackground()

注意:这种方案依赖UITabBar的私有子视图结构,虽然在大多数iOS版本中稳定,但版本更新时需要测试兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 10:01:46