如何在iOS 7和iOS 8上正确自定义UITabBar和UITabBarItem?

15

我在Google上搜索了很多,但没有找到一个直截了当而且完整的答案。

我想自定义我的UITabBarController,使之满足以下要求:

  1. UITabBar本身完全是黑色的
  2. 项目标题的文本颜色在非高亮状态下为白色
  3. 项目标题的文本颜色在高亮状态下为红色
  4. 在选项卡栏中使用多彩图标

1. 将UITabBar变成黑色

我猜我需要使用UIAppearance API来做到这一点,实际上我能够使用以下代码将UITabBar变成黑色:[[UITabBar appearance] setBarTintColor:[UIColor blackColor]];

2. 和 3. 修改项目标题的颜色

然而,项目文本的颜色似乎不符合我的要求,在Google搜索后,以下解决方案对我有意义,但它只将非高亮状态改为白色,高亮状态仍然是白色...

NSDictionary *titleAttributes = @{NSForegroundColorAttributeName : [UIColor whiteColor]};
[[UITabBarItem appearance] setTitleTextAttributes:titleAttributes forState:UIControlStateNormal];

UIColor *titleHighlightedColor = [UIColor redColor]; 
NSDictionary *highlightedTitleAttributes = @{NSForegroundColorAttributeName : titleHighlightedColor};
[[UITabBarItem appearance] setTitleTextAttributes:highlightedTitleAttributes forState:UIControlStateHighlighted];

4. 多彩图标

关于多彩图标,目前我的做法是在Storyboard中简单地将图标设置为:

enter image description here

但这并不符合我的要求,因为当项目没有被选择时,它只会以灰色显示整个图标。而当项目被选择时,图标会完全消失。

这是原始图标:

enter image description here

这是项目未被选择时的外观:

enter image description here

这是被选择时的状态,如上所述,图标完全消失:

enter image description here

那么,我的问题是如何精确实现上述要求?我当前缺少什么?我是否最好在代码中完成所有操作而不是在Storyboard中完成?

注意:我的目标是iOS版本大于7.0,如果行为在iOS 7和iOS 8之间有差异,请包括任何特定于版本的信息。

2个回答

21

我曾经遇到过和你一样的问题。据我所知,对于不同版本的iOS,没有区别。


我是通过编程来解决这个问题的,方法如下:

  1. 将选项卡栏的颜色设置为黑色的代码如下(你已经说了)(在AppDelegate中):

    UITabBar.appearance().barTintColor = UIColor.blackColor()

  2. 要设置不同状态的标题颜色,我使用了以下代码(在AppDelegate中):

    UITabBarItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName!: UIColor.redColor()], forState:.Selected)
    UITabBarItem.appearance().setTitleTextAttributes([NSForegroundColorAttributeName!: UIColor.whiteColor()], forState:.Normal)
    
    (第四点已包含在内。)您可以通过在程序中设置图像并将呈现模式 (imageWithRenderingMode:) 更改为 UIImageRenderingMode.AlwaysOriginal 来实现不同项目颜色、多彩的图标以及不同状态下的不同项目颜色,效果如下所示(在所有视图控制器的第一个视图控制器类中执行此操作):
    var recentsItem = self.tabBarController!.tabBar.items![0] as UITabBarItem
    var recentsItemImage = UIImage(named:"recents.png")!.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
    var recentsItemImageSelected = UIImage(named: "recentsSelected.png")!.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
    recentsItem.image = recentsItemImage
    recentsItem.selectedImage = recentsItemImageSelected
    
    我希望这可以帮助您,如果您还有任何问题,请随时问我。

我对 3. 的方法其实是正确的,只不过我的错误在于选择了 UIControlStateHighlighted 而不是 UIControlStateSelected,感谢您指出! :) 另外,关于 UIImageRenderingMode 的提示真的很有帮助! - nburk
关于 #2 : 我们应该记住,UITabBarItem.appearance().setTitleTextAttributes只能用来自定义.font .foregroundColor.shadow,而不能用于其他键(参考https://developer.apple.com/documentation/uikit/uibaritem/1616414-settitletextattributes)。 - Axel Guilmin

6

smudis提供的解决方案非常好,由于我没有足够的声望来评论,因此我决定发布smudis解决方案的第三部分Objective-C代码,以防有人需要:

将上述代码输入到AppDelegate的方法application:didFinishLaunchingWithOptions:中,以获取tabBar的引用。

UITabBarController *tbc = (UITabBarController*)self.window.rootViewController;
UITabBar *tb = tbc.tabBar;

然后,可以按照以下方式进行图像调整:
for (UITabBarItem *tbi in tb.items) {
    tbi.selectedImage = [tbi.selectedImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    tbi.image = [tbi.image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接