如何实现与App Store风格一致的UIKit TabBar(颜色匹配问题)
实现与App Store样式一致的UIKit TabBar
我想要实现和App Store完全一致的UIKit TabBar,要求渐变效果、背景色、选中/未选中状态颜色都完全匹配,但用下面的Swift代码实现后,效果和预期不符。
效果对比
目标效果(App Store样式)

当前实现效果

现有Swift代码
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) tabBar.barTintColor = .clear UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.lightGray.withAlphaComponent(0.5)], for: .normal) UITabBarItem.appearance().setTitleTextAttributes([NSAttributedString.Key.foregroundColor: UIColor.white.withAlphaComponent(0.7)], for: .selected) if #available(iOS 13.0, *) { var appearance = tabBar.standardAppearance // Set a more transparent background with a blur effect appearance.backgroundEffect = UIBlurEffect(style: .systemMaterial) // Set tab bar item colors setTabBarItemColors(appearance.stackedLayoutAppearance) setTabBarItemColors(appearance.inlineLayoutAppearance) setTabBarItemColors(appearance.compactInlineLayoutAppearance) // Set tab bar item badge appearance setTabBarItemBadgeAppearance(appearance.stackedLayoutAppearance) setTabBarItemBadgeAppearance(appearance.inlineLayoutAppearance) setTabBarItemBadgeAppearance(appearance.compactInlineLayoutAppearance) tabBar.standardAppearance = appearance } else { // Fallback for earlier iOS versions if needed } } @available(iOS 13.0, *) private func setTabBarItemColors(_ itemAppearance: UITabBarItemAppearance) { // Set colors for normal and selected states itemAppearance.normal.iconColor = .systemGray itemAppearance.normal.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.systemGray.withAlphaComponent(0.5)] itemAppearance.selected.iconColor = .label itemAppearance.selected.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.label.withAlphaComponent(0.7)] } @available(iOS 13.0, *) private func setTabBarItemBadgeAppearance(_ itemAppearance: UITabBarItemAppearance) { // Set badge background color, text color, and position adjustment itemAppearance.normal.badgeBackgroundColor = .systemRed itemAppearance.normal.badgeTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white] itemAppearance.normal.badgePositionAdjustment = UIOffset(horizontal: 1, vertical: -1) }
修正方案
修正后的完整代码
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) if #available(iOS 13.0, *) { configureTabBarAppearance() addTabBarGradientBackground() } else { // iOS 12及以下兼容处理 tabBar.barTintColor = .clear tabBar.backgroundImage = createGradientImage() UITabBarItem.appearance().setTitleTextAttributes([.foregroundColor: UIColor.white.withAlphaComponent(0.4)], for: .normal) UITabBarItem.appearance().setTitleTextAttributes([.foregroundColor: UIColor.white], for: .selected) UITabBar.appearance().tintColor = UIColor.white.withAlphaComponent(0.4) UITabBar.appearance().selectedImageTintColor = .white } } @available(iOS 13.0, *) private func configureTabBarAppearance() { var appearance = UITabBarAppearance() // 匹配App Store的深色模糊背景 appearance.backgroundEffect = UIBlurEffect(style: .systemUltraThinMaterialDark) // 移除默认阴影线 appearance.shadowImage = UIImage() appearance.shadowColor = nil // 配置TabBarItem样式 let itemAppearance = UITabBarItemAppearance() // 未选中状态:浅白色(低透明度) itemAppearance.normal.iconColor = UIColor.white.withAlphaComponent(0.4) itemAppearance.normal.titleTextAttributes = [ NSAttributedString.Key.foregroundColor: UIColor.white.withAlphaComponent(0.4), NSAttributedString.Key.font: UIFont.systemFont(ofSize: 10) ] // 选中状态:纯白色 itemAppearance.selected.iconColor = .white itemAppearance.selected.titleTextAttributes = [ NSAttributedString.Key.foregroundColor: UIColor.white, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 10) ] // 应用到所有布局样式 appearance.stackedLayoutAppearance = itemAppearance appearance.inlineLayoutAppearance = itemAppearance appearance.compactInlineLayoutAppearance = itemAppearance // 配置徽章样式,对齐App Store itemAppearance.normal.badgeBackgroundColor = .systemRed itemAppearance.normal.badgeTextAttributes = [.foregroundColor: UIColor.white] itemAppearance.normal.badgePositionAdjustment = UIOffset(horizontal: 2, vertical: -2) tabBar.standardAppearance = appearance // iOS 15+适配滚动到顶部的样式 if #available(iOS 15.0, *) { tabBar.scrollEdgeAppearance = appearance } } @available(iOS 13.0, *) private func addTabBarGradientBackground() { // 添加底部渐变暗化层,模拟App Store效果 let gradientLayer = CAGradientLayer() gradientLayer.colors = [ UIColor.black.withAlphaComponent(0).cgColor, UIColor.black.withAlphaComponent(0.3).cgColor ] gradientLayer.frame = tabBar.bounds gradientLayer.startPoint = CGPoint(x: 0.5, y: 0) gradientLayer.endPoint = CGPoint(x: 0.5, y: 1) tabBar.layer.insertSublayer(gradientLayer, at: 0) } // iOS 12及以下生成渐变背景图 private func createGradientImage() -> UIImage? { let gradientLayer = CAGradientLayer() gradientLayer.colors = [ UIColor.black.withAlphaComponent(0).cgColor, UIColor.black.withAlphaComponent(0.3).cgColor ] gradientLayer.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: tabBar.bounds.height) UIGraphicsBeginImageContext(gradientLayer.bounds.size) gradientLayer.render(in: UIGraphicsGetCurrentContext()!) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() return image }
核心修正点
- 背景模糊效果:将原代码的
.systemMaterial替换为.systemUltraThinMaterialDark,完全匹配App Store的深色半透明模糊 - 颜色统一:未选中状态使用
UIColor.white.withAlphaComponent(0.4),选中状态用纯白色,消除原代码中颜色不匹配的问题 - 冲突移除:删除全局
UITabBarItem.appearance()的重复设置,避免和standardAppearance的样式冲突 - 渐变增强:添加渐变暗化层,还原App Store TabBar底部的渐变过渡效果
- iOS版本适配:覆盖iOS 13+和iOS 12及以下的场景,同时适配iOS 15的
scrollEdgeAppearance,确保滚动时样式一致
内容的提问来源于stack exchange,提问作者Ratnesh Pathak
相关产品推荐
相关产品推荐

