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

Swift 3:如何为选中的Tab添加顶部彩色边框

嘿,这个需求我之前做过类似的,在Swift 3里给选中的Tab添加顶部彩色边框其实不难,给你两种实用的方案,你可以根据自己的场景选:

方案一:给TabBar添加全局顶部指示器(推荐)

这种方法是在TabBar的顶部添加一个固定高度的彩色视图,切换Tab时让这个视图移动到对应Tab的位置,实现起来简单且统一。

实现步骤:

  1. 创建一个自定义的UITabBarController子类,用来管理TabBar和指示器
  2. 在初始化方法里添加指示器视图,并设置初始位置
  3. 监听Tab切换事件,动态更新指示器的位置和宽度

完整代码:

import UIKit

class CustomTabBarController: UITabBarController {
    
    // 顶部指示器视图
    private let tabIndicator = UIView()
    // 指示器高度,可自定义
    private let indicatorHeight: CGFloat = 3
    // 指示器颜色,替换成你需要的颜色
    private let indicatorColor = UIColor(red: 0.12, green: 0.56, blue: 1.0, alpha: 1.0)
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 设置当前TabBarController的代理
        self.delegate = self
        
        // 配置指示器的初始样式
        tabIndicator.backgroundColor = indicatorColor
        tabBar.addSubview(tabIndicator)
        // 确保指示器在最上层,不被其他元素遮挡
        tabBar.bringSubview(toFront: tabIndicator)
        
        // 初始化指示器到第一个选中Tab的位置
        updateIndicatorFrame()
    }
    
    // 更新指示器的位置和宽度
    private func updateIndicatorFrame() {
        guard let tabItems = tabBar.items, let selectedItem = tabBar.selectedItem else { return }
        
        // 方式1:所有Tab宽度均分(适合Tab数量固定且样式统一的情况)
        let selectedIndex = tabItems.index(of: selectedItem)!
        let tabCount = CGFloat(tabItems.count)
        let tabWidth = tabBar.bounds.width / tabCount
        
        // 方式2:适配Tab宽度不一致的情况(比如带角标、文字长度不同)
        // if let selectedItemFrame = selectedItem.value(forKey: "view")?.frame {
        //     tabIndicator.frame = CGRect(x: selectedItemFrame.origin.x, y: 0, width: selectedItemFrame.width, height: indicatorHeight)
        // }
        
        // 设置指示器的frame,并添加平滑动画
        UIView.animate(withDuration: 0.2) {
            self.tabIndicator.frame = CGRect(
                x: CGFloat(selectedIndex) * tabWidth,
                y: 0,
                width: tabWidth,
                height: self.indicatorHeight
            )
        }
    }
}

// 实现UITabBarControllerDelegate,监听Tab切换事件
extension CustomTabBarController: UITabBarControllerDelegate {
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        updateIndicatorFrame()
    }
}

使用方法:

把你项目中原有的UITabBarController替换成这个自定义的CustomTabBarController即可(可以在Storyboard里设置类名,或者代码初始化)。


方案二:自定义TabBarItem视图,单独控制顶部边框

如果需要给每个Tab定制不同的顶部边框样式(比如不同颜色),可以用这种方法,给每个TabBarItem设置自定义视图,在选中时显示顶部边框。

实现步骤:

  1. 创建自定义的UIView子类,作为TabBarItem的显示视图,包含顶部边框、图标和文字
  2. 在每个ViewController里,给对应的tabBarItem设置这个自定义视图
  3. 在TabBarController里监听切换事件,更新每个自定义视图的选中状态

完整代码:

import UIKit

// 自定义TabBarItem的视图
class CustomTabBarItemView: UIView {
    
    private let topBorder = UIView()
    private let indicatorHeight: CGFloat = 3
    // 可以根据需要设置不同颜色,或者外部传入
    private let indicatorColor = UIColor.orange
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupSubviews()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupSubviews()
    }
    
    // 初始化子视图
    private func setupSubviews() {
        // 配置顶部边框
        topBorder.backgroundColor = indicatorColor
        topBorder.isHidden = true
        addSubview(topBorder)
        
        // 用AutoLayout布局顶部边框
        topBorder.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            topBorder.topAnchor.constraint(equalTo: self.topAnchor),
            topBorder.leadingAnchor.constraint(equalTo: self.leadingAnchor),
            topBorder.trailingAnchor.constraint(equalTo: self.trailingAnchor),
            topBorder.heightAnchor.constraint(equalToConstant: indicatorHeight)
        ])
    }
    
    // 切换选中状态的方法
    func setTabSelected(_ isSelected: Bool) {
        UIView.animate(withDuration: 0.2) {
            self.topBorder.isHidden = !isSelected
            self.topBorder.alpha = isSelected ? 1.0 : 0.0
        }
    }
}

// 在ViewController中设置自定义TabBarItem
class HomeViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 创建自定义视图,尺寸适配TabBar高度
        let customTabView = CustomTabBarItemView(frame: CGRect(x: 0, y: 0, width: 80, height: tabBarController?.tabBar.bounds.height ?? 49))
        
        // 添加图标
        let iconView = UIImageView(image: UIImage(named: "home_icon"))
        iconView.frame = CGRect(x: 28, y: 8, width: 24, height: 24)
        customTabView.addSubview(iconView)
        
        // 添加文字
        let titleLabel = UILabel(frame: CGRect(x: 15, y: 36, width: 50, height: 12))
        titleLabel.text = "首页"
        titleLabel.font = UIFont.systemFont(ofSize: 10)
        titleLabel.textAlignment = .center
        titleLabel.textColor = UIColor.gray
        customTabView.addSubview(titleLabel)
        
        // 设置给当前TabBarItem
        tabBarItem.customView = customTabView
        
        // 初始选中状态
        if tabBarController?.selectedIndex == 0 {
            customTabView.setTabSelected(true)
            titleLabel.textColor = UIColor.orange
        }
    }
}

// 在自定义TabBarController中监听切换,更新状态
extension CustomTabBarController: UITabBarControllerDelegate {
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        guard let tabItems = tabBar.items else { return }
        
        for (index, item) in tabItems.enumerated() {
            if let customView = item.customView as? CustomTabBarItemView {
                let isSelected = index == tabBarController.selectedIndex
                customView.setTabSelected(isSelected)
                
                // 同步更新文字颜色(可选)
                if let label = customView.subviews.first(where: { $0 is UILabel }) as? UILabel {
                    label.textColor = isSelected ? UIColor.orange : UIColor.gray
                }
            }
        }
    }
}

一些注意事项
  • 方案一中的两种宽度计算方式,根据你的Tab样式选择:如果所有Tab宽度一致,用均分方式;如果Tab宽度不同,用获取item实际frame的方式。
  • 颜色可以任意自定义,比如用RGB值或者系统预设颜色。
  • 动画时长可以根据需求调整,让切换更流畅。
  • 如果使用Storyboard,记得把TabBarController的Class设置为你自定义的CustomTabBarController。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 04:11:49