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

如何为选中的Tab Bar Item添加边框/圆圈而非仅改色?

当然可以实现!给选中的TabBarItem添加方框/圆圈样式的方法

给选中的TabBarItem设置方框或圆圈标记,而非仅依赖颜色区分,是完全可行的,下面我会分享几种不同场景下的靠谱实现方案:

方法一:自定义选中状态图标(最简单直观)

这种方法适合需求简单的场景——直接为每个TabBarItem准备带方框/圆圈的选中态图标,以及普通的未选中态图标,直接赋值给TabBarItem的对应属性即可。

步骤:

  1. 准备两套图标:比如home_normal.png(普通图标)、home_selected.png(带蓝色圆圈的选中图标)
  2. 设置TabBarItem时,指定image和selectedImage,并设置渲染模式为alwaysOriginal(避免系统自动 tint 颜色):
// 示例:创建第一个TabBarItem
let homeItem = UITabBarItem(
    title: "首页",
    image: UIImage(named: "home_normal")?.withRenderingMode(.alwaysOriginal),
    selectedImage: UIImage(named: "home_selected")?.withRenderingMode(.alwaysOriginal)
)
// 把item赋值给对应的ViewController
homeViewController.tabBarItem = homeItem

这种方法优势是实现简单,无需复杂自定义视图;缺点是样式固定,无法动态调整圆圈/方框的大小、颜色。

方法二:自定义TabBar(灵活度最高)

如果需要动态调整标记样式(比如随主题切换颜色、调整圆圈大小),可以通过继承UITabBar自定义视图逻辑,手动给选中的Item添加圆圈/方框图层。

步骤:

  1. 创建自定义TabBar类:
class CustomTabBar: UITabBar {
    // 标记图层的标识,方便后续移除旧图层
    private let markerLayerName = "tabSelectionMarker"
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        // 先移除之前添加的标记图层,避免重复叠加
        subviews.forEach { view in
            view.layer.sublayers?.filter { $0.name == markerLayerName }.forEach { $0.removeFromSuperlayer() }
        }
        
        // 获取当前选中的索引
        guard let selectedIndex = tabBarController?.selectedIndex else { return }
        
        // 遍历TabBar的子视图,找到对应选中的Item视图
        for (index, view) in subviews.enumerated() {
            // 系统TabBar的Item视图是UIControl类型,通过索引匹配选中项
            if view is UIControl, index == selectedIndex {
                // 创建圆圈标记图层
                let markerLayer = CAShapeLayer()
                markerLayer.name = markerLayerName
                
                // 1. 画圆圈:中心在Item视图中心,半径可自定义
                let circlePath = UIBezierPath(
                    arcCenter: CGPoint(x: view.bounds.midX, y: view.bounds.midY),
                    radius: 22, // 圆圈半径
                    startAngle: 0,
                    endAngle: CGFloat.pi * 2,
                    clockwise: true
                )
                
                // 2. 或者画方框:使用inset调整边框与Item的间距
                // let rectPath = UIBezierPath(rect: view.bounds.insetBy(dx: 6, dy: 6))
                
                markerLayer.path = circlePath.cgPath
                markerLayer.strokeColor = UIColor.systemBlue.cgColor // 边框颜色
                markerLayer.fillColor = UIColor.clear.cgColor // 填充透明
                markerLayer.lineWidth = 2 // 边框宽度
                
                view.layer.addSublayer(markerLayer)
            }
        }
    }
    
    // 监听选中状态变化,触发重新布局更新标记
    override func setSelectedItem(_ selectedItem: UITabBarItem?) {
        super.setSelectedItem(selectedItem)
        setNeedsLayout()
    }
}
  1. 在TabBarController中使用自定义TabBar:
class CustomTabBarController: UITabBarController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // 替换系统TabBar为自定义的
        tabBar = CustomTabBar()
    }
}

这种方法优势是完全可控,可根据需求动态修改标记样式;缺点是需要处理系统TabBar子视图的遍历逻辑,要注意适配不同iOS版本的视图结构变化。

方法三:利用UITabBarAppearance(iOS13+官方推荐)

从iOS13开始,苹果提供了UITabBarAppearance统一配置TabBar样式,我们可以通过自定义选中态的背景图实现圆圈/方框标记。

步骤:

  1. 创建带圆圈/方框的自定义背景图(代码绘制,无需资源文件):
extension UIImage {
    static func createMarkerImage(size: CGSize, color: UIColor, lineWidth: CGFloat = 2) -> UIImage {
        UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
        let context = UIGraphicsGetCurrentContext()!
        
        // 画圆圈
        let circlePath = UIBezierPath(
            arcCenter: CGPoint(x: size.width/2, y: size.height/2),
            radius: min(size.width, size.height)/2 - lineWidth,
            startAngle: 0,
            endAngle: CGFloat.pi*2,
            clockwise: true
        )
        color.setStroke()
        circlePath.lineWidth = lineWidth
        circlePath.stroke()
        
        let image = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return image
    }
}
  1. 配置TabBarAppearance并应用到TabBar:
class CustomTabBarController: UITabBarController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        let appearance = UITabBarAppearance()
        
        // 配置选中态的样式
        let selectedAppearance = UITabBarItemAppearance()
        // 设置选中时的图标颜色
        selectedAppearance.iconColor = .systemBlue
        // 设置自定义的圆圈背景图
        selectedAppearance.backgroundImage = UIImage.createMarkerImage(
            size: CGSize(width: 60, height: 60),
            color: .systemBlue
        )
        
        // 应用选中态配置到堆叠布局(适合大多数场景)
        appearance.stackedLayoutAppearance.selected = selectedAppearance
        
        // 应用配置到TabBar
        tabBar.standardAppearance = appearance
        // iOS15+需要额外设置scrollEdgeAppearance,适配滚动到顶部的情况
        if #available(iOS 15.0, *) {
            tabBar.scrollEdgeAppearance = appearance
        }
    }
}

这种方法优势是符合苹果设计规范,适配性更好;缺点是仅支持iOS13及以上版本。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 07:04:42