UITabBar 在 iOS7 上更改一个 UITabBarItem 的背景颜色
Posted
技术标签:
【中文标题】UITabBar 在 iOS7 上更改一个 UITabBarItem 的背景颜色【英文标题】:UITabBar change background color of one UITabBarItem on iOS7 【发布时间】:2013-12-05 21:01:45 【问题描述】:我可以更改UITabBar
中特定UITabBarItem
的背景颜色吗?
我知道如何更改所选背景的所有背景,使用:
[[UITabBar appearance] setBarTintColor:[UIColor redColor]];
[[UITabBar appearance] setTintColor:[UIColor blueColor]];
[[UITabBar appearance] setSelectedImageTintColor:[UIColor yellowColor]];
但是可以只对一项不进行子类化吗?
谢谢
【问题讨论】:
【参考方案1】:您可以在父 tabBar 中添加子视图,并在子视图上设置背景颜色。您可以使用 tabBar 框架尺寸计算您的 tabBarItem 的偏移量和宽度,然后在下面插入子视图。
示例(在 Swift 中):
// Add background color to middle tabBarItem
let itemIndex = 2
let bgColor = UIColor(red: 0.08, green: 0.726, blue: 0.702, alpha: 1.0)
let itemWidth = tabBar.frame.width / CGFloat(tabBar.items!.count)
let bgView = UIView(frame: CGRectMake(itemWidth * itemIndex, 0, itemWidth, tabBar.frame.height))
bgView.backgroundColor = bgColor
tabBar.insertSubview(bgView, atIndex: 0)
【讨论】:
谢谢@nathan.f77 它有效,唯一的问题是只允许我更改背景颜色(我接受了你的回答,因为这实际上是我的问题)。但是当我改变背景颜色时,我还需要改变这个项目的色调.. 现在,我在项目位置的 tarBar 顶部添加一个按钮...... :( 当我复制粘贴这段代码时,xCode 报错:'Could not find member frame' on the line: let bgView =... @ChrisHarrison - 这很奇怪,因为您在上面的行中调用了tabBar.frame
,所以它也应该在那里给出错误。
@nathan.f77 改成这一行: let itemWidth: CGFloat = tabBar.frame.width / CGFloat(tabBar.items!.count) 解决问题。
这真是太聪明了。我认为 insertSubview: 会阻止图标和文本。原来没有。【参考方案2】:
在 Swift 中:
此解决方案适用于使用 Auto Layout
的应用程序。其他解决方案的主要区别在于:tabBar.frame.width
没有获得实际设备的屏幕宽度。所以,bgView
出现在错误的地方。
你可以用这个来修复它:UIScreen.main.bounds.width
let tabWidth: CGFloat = UIScreen.main.bounds.width / CGFloat(self.tabbar!.items!.count)
let tabIndex: CGFloat = 2
let bgColor: UIColor = .redColor
let bgView = UIView(frame: CGRectMake(tabWidth * tabIndex, 0, tabWidth, 49))
bgView.backgroundColor = bgColor
self.tabbar!.insertSubview(bgView, atIndex: 0)
49 是默认高度
UITabbar
【讨论】:
不确定这是不是由最近对自动布局的更改引起的,但这不起作用。在最后一行代码的索引 0 处插入新视图将使其他子视图(很可能是背景视图)覆盖我们的新视图。与所有视图定义一样,子视图的顺序对渲染很重要。要将新视图放在背景视图之上但在 tabIndex 项目的图像和文本之下,这似乎可以解决 ios 9/Xcode 7.3 的问题:self.tabBar!.insertSubview(bgView, atIndex: tabIndex + 2) 完美!谢谢!我确认它适用于 iOS 12.1 和 Xcode 10.1。【参考方案3】:Objective C 解决方案:
int itemIndex = 3;
UIColor* bgColor = [UIColor colorWithRed:(245/255.f) green:(192/255.f) blue:(47/255.f) alpha:1];
float itemWidth = self.tabBarController.tabBar.frame.size.width / 5.0f; //5 = tab bar items
UIView* bgView = [[UIView alloc]initWithFrame: CGRectMake(itemWidth*itemIndex, 0,itemWidth, self.tabBarController.tabBar.frame.size.height)];
bgView.backgroundColor = bgColor;
[self.tabBarController.tabBar insertSubview:bgView atIndex:1];
【讨论】:
【参考方案4】:为 Swift 4 更新:
let itemIndex: CGFloat = 2.0
let bgColor = UIColor.ownBlue
let itemWidth = tabBar.frame.width / CGFloat(tabBar.items!.count)
let bgView = UIView(frame: CGRect(x: itemWidth * itemIndex, y: 0, width: itemWidth, height: tabBar.frame.height))
bgView.backgroundColor = bgColor
tabBar.insertSubview(bgView, at: 0)
【讨论】:
【参考方案5】:您无法使用 tint color 属性真正做到这一点。请参阅this post 关于即使setSelectedImageTintColor
似乎也没有真正起作用的事实(我上次检查时没有)。
解决方案是动态更改相关项目的tintColor
。您可以通过实现UITabBarDelegate
方法tabBar:didSelectItem:
例如在所选项目更改时执行此操作ad hoc在应用委托中。
【讨论】:
嘿@Mundi,谢谢你的回答。我不想在选择时更改它,但一直都在更改它。我基本上有五个按钮都是白色背景的,除了中间的那个总是黑色背景。 @HuguesBR 你找到方法了吗? 不是真的,我在标签栏视图中添加了一个 uibutton,它掩盖了相关标签以达到目的...【参考方案6】:比赛迟到了,但我就是这样做的。我使标签看起来像按钮,具有圆形视图。上面的答案,在设备旋转或应用发送到拆分窗口时会出现问题。
此解决方案将背景直接与每个选项卡结合,使用自动布局,因此它们自然会跟随选项卡栏的变化。
这是在 UITabBarController 的自定义子类上完成的。
首先,我设置选项卡项中图标的颜色(未选中为白色,选中为黑色),然后,我迭代选项卡,并为每个选项卡插入背景,使用自动布局让它们切入标签:
override func viewDidLoad()
super.viewDidLoad()
let appearance = UITabBarAppearance()
appearance.stackedLayoutAppearance.normal.iconColor = .white
appearance.stackedLayoutAppearance.selected.iconColor = .black
appearance.inlineLayoutAppearance.normal.iconColor = .white
appearance.inlineLayoutAppearance.selected.iconColor = .black
appearance.compactInlineLayoutAppearance.normal.iconColor = .white
appearance.compactInlineLayoutAppearance.selected.iconColor = .black
tabBar.subviews.forEach
if let item = $0 as? UIControl
let wrapper = UIView()
wrapper.isUserInteractionEnabled = false
wrapper.clipsToBounds = true
wrapper.backgroundColor = tabBar.tintColor
wrapper.layer.cornerRadius = 8
item.insertSubview(wrapper, at: 0)
wrapper.translatesAutoresizingMaskIntoConstraints = false
wrapper.leadingAnchor.constraint(equalTo: item.leadingAnchor).isActive = true
wrapper.trailingAnchor.constraint(equalTo: item.trailingAnchor).isActive = true
wrapper.topAnchor.constraint(equalTo: item.topAnchor).isActive = true
wrapper.bottomAnchor.constraint(equalTo: item.bottomAnchor).isActive = true
之所以如此,是因为标签栏将标签项实现为 UIControl 的内部子类,即 UIView。
我可以在控件下方添加视图。
这最终看起来像这样:
注意:关闭用户交互很重要,就像在 0 处插入一样。
缺点是无法判断哪个项目是选定的(在创建背景图像时)。
另外注意: Apple REALLY 不希望我们在标签栏中胡闹,所以我可以看到这种方法(以及上面的方法) ),在未来的一些操作系统升级中中断。
【讨论】:
以上是关于UITabBar 在 iOS7 上更改一个 UITabBarItem 的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iOS 7.1 中更改 TabBar 上的图像和标签颜色?