Swift 3:如何为选中的Tab添加顶部彩色边框
嘿,这个需求我之前做过类似的,在Swift 3里给选中的Tab添加顶部彩色边框其实不难,给你两种实用的方案,你可以根据自己的场景选:
方案一:给TabBar添加全局顶部指示器(推荐)
这种方法是在TabBar的顶部添加一个固定高度的彩色视图,切换Tab时让这个视图移动到对应Tab的位置,实现起来简单且统一。
实现步骤:
- 创建一个自定义的
UITabBarController子类,用来管理TabBar和指示器 - 在初始化方法里添加指示器视图,并设置初始位置
- 监听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设置自定义视图,在选中时显示顶部边框。
实现步骤:
- 创建自定义的
UIView子类,作为TabBarItem的显示视图,包含顶部边框、图标和文字 - 在每个ViewController里,给对应的tabBarItem设置这个自定义视图
- 在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
相关产品推荐
相关产品推荐

