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

Swift设置TabBar选中项透明背景及添加选中项阴影

嘿,我来帮你搞定这个TabBar的选中状态样式和阴影效果!

实现TabBar选中项背景色与阴影效果

1. 自定义UITabBar子类(最灵活可控的方案)

系统UITabBar没有直接提供设置选中项背景的API,所以我们自定义一个子类来实现需求:

首先创建CustomTabBar.swift文件:

import UIKit

class CustomTabBar: UITabBar {
    // 选中项的背景视图(提前配置好阴影)
    private var selectedBackgroundView: UIView = {
        let view = UIView()
        view.backgroundColor = YourColorClass.mainDarkBlueTransparent // 替换成你的颜色定义类
        view.layer.cornerRadius = 20 // 可选:给背景加圆角,视觉更柔和
        // 配置阴影属性
        view.layer.shadowColor = UIColor.black.cgColor
        view.layer.shadowOffset = CGSize(width: 0, height: 2)
        view.layer.shadowOpacity = 0.3
        view.layer.shadowRadius = 4
        view.clipsToBounds = false // 必须设为false,否则阴影会被裁剪掉
        return view
    }()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupInitialConfig()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupInitialConfig()
    }
    
    private func setupInitialConfig() {
        self.barTintColor = YourColorClass.mainDarkBlue // 设置TabBar整体背景色
        addSubview(selectedBackgroundView)
        selectedBackgroundView.isHidden = true // 初始隐藏,选中第一个item时再显示
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        // 每次布局更新时,同步背景视图的位置
        updateSelectedBackgroundPosition()
    }
    
    override var selectedItem: UITabBarItem? {
        didSet {
            // 选中项变化时,更新背景位置
            updateSelectedBackgroundPosition()
        }
    }
    
    private func updateSelectedBackgroundPosition() {
        guard let selectedItem = selectedItem else {
            selectedBackgroundView.isHidden = true
            return
        }
        
        selectedBackgroundView.isHidden = false
        // 通过runtime获取选中item的frame
        guard let itemFrame = selectedItem.value(forKey: "view")?.frame else { return }
        
        // 调整背景视图的大小和位置,你可以根据需求修改参数
        selectedBackgroundView.frame = CGRect(
            x: itemFrame.origin.x + 8, // 左右留8pt空白,避免背景贴边
            y: 8, // 顶部留8pt空白,避开TabBar顶部边缘
            width: itemFrame.width - 16,
            height: self.bounds.height - 16
        )
        
        // 把背景视图放到所有item视图的下层,避免遮挡图标和文字
        sendSubviewToBack(selectedBackgroundView)
    }
}

2. 在TabBarController中替换为自定义TabBar

接下来,在你的TabBarController里把系统默认的TabBar替换成我们自定义的:

class YourTabBarController: UITabBarController {
    override func viewDidLoad() {
        super.viewDidLoad()
        // 替换自定义TabBar
        let customTabBar = CustomTabBar()
        setValue(customTabBar, forKey: "tabBar")
    }
}

3. 关键细节提示

  • 透明度生效:mainDarkBlueTransparent的alpha值已经设为0.8,直接赋值给背景视图即可生效,无需额外调整。
  • 阴影显示:一定要把clipsToBounds设为false,否则阴影会被视图的边界裁剪掉;你可以根据需求修改阴影的颜色、偏移量、透明度和模糊半径,调出你想要的效果。
  • 位置调整:修改selectedBackgroundView.frame的参数,就能调整背景的大小和留白,让样式更贴合你的设计。
  • 避免遮挡:sendSubviewToBack(selectedBackgroundView)能确保背景视图不会覆盖TabBarItem的图标和文字,优先级最低。

备选方案(无需自定义子类)

如果不想自定义TabBar子类,也可以在TabBarController中监听选中事件,动态添加背景视图:

class YourTabBarController: UITabBarController {
    private var selectedBackgroundView: UIView?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.tabBar.barTintColor = YourColorClass.mainDarkBlue
        setupSelectedBackgroundView()
        self.delegate = self // 监听选中事件
    }
    
    private func setupSelectedBackgroundView() {
        let view = UIView()
        view.backgroundColor = YourColorClass.mainDarkBlueTransparent
        view.layer.cornerRadius = 20
        view.layer.shadowColor = UIColor.black.cgColor
        view.layer.shadowOffset = CGSize(width: 0, height: 2)
        view.layer.shadowOpacity = 0.3
        view.layer.shadowRadius = 4
        view.clipsToBounds = false
        self.tabBar.addSubview(view)
        self.tabBar.sendSubviewToBack(view)
        selectedBackgroundView = view
        updateSelectedBackgroundPosition() // 初始位置更新
    }
    
    private func updateSelectedBackgroundPosition() {
        guard let selectedItem = self.selectedItem, let view = selectedBackgroundView else { return }
        guard let itemFrame = selectedItem.value(forKey: "view")?.frame else { return }
        view.frame = CGRect(
            x: itemFrame.origin.x + 8,
            y: 8,
            width: itemFrame.width - 16,
            height: self.tabBar.bounds.height - 16
        )
    }
}

extension YourTabBarController: UITabBarControllerDelegate {
    func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) {
        updateSelectedBackgroundPosition() // 选中项变化时更新位置
    }
}

这个方案不需要自定义子类,适合快速实现,但灵活性稍差。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 07:37:59