iOS 7中UITabBar未显示选定的项目图像

49

这些图标在iOS 6中显示正常,但在iOS 7中没有显示。我在viewController的viewDidLoad方法中设置了选定状态。当用户选择一个标签栏项时,图像会消失。 以下是我的代码:

UITabBar *tabBar = self.tabBarController.tabBar;
if ([UITabBar instancesRespondToSelector:@selector(setSelectedImageTintColor:)]) {
    [self.tabBarController.tabBar setSelectedImageTintColor:[UIColor whiteColor]];
}
UITabBarItem *item0 = [tabBar.items objectAtIndex:0];
UITabBarItem *item1 = [tabBar.items objectAtIndex:1];
UITabBarItem *item2 = [tabBar.items objectAtIndex:2];
UITabBarItem *item3 = [tabBar.items objectAtIndex:3];
[item0 setTitle:@"Home"];
[item1 setTitle:@"Calendar"];
[item2 setTitle:@"News"];
[item3 setTitle:@"My Events"];
[item0 setFinishedSelectedImage:[UIImage imageNamed:@"homeIconSelected.png"] withFinishedUnselectedImage:[UIImage imageNamed:@"home2.png"]];
[item1 setFinishedSelectedImage:[UIImage imageNamed:@"Calendar"] withFinishedUnselectedImage:[UIImage imageNamed:@"CalendarIconSelected"]];
[item2 setFinishedSelectedImage:[UIImage imageNamed:@"NewsIconSelected"] withFinishedUnselectedImage:[UIImage imageNamed:@"News"]];
[item3 setFinishedSelectedImage:[UIImage imageNamed:@"EventsIconSelected"] withFinishedUnselectedImage:[UIImage imageNamed:@"Events"]];
[item1 imageInsets];
[item2 imageInsets];
[item3 imageInsets];
20个回答

97

你需要使用 initWithTitle:image:selectedImage 来设置选项卡项目。

[[UITabBarItem alloc] initWithTitle:@"title" image:image selectedImage:imageSel];

与更改 UIImage 渲染模式相结合:

imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal

或者(为了应用父视图模板的着色蒙版,除非您选择使用上述渲染模式退出,否则此选项是Tab栏项目的默认选项)

imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate

这里是一个选项卡栏单个选项的代码示例:

UIImage *musicImage = [UIImage imageNamed:@"music.png"];
UIImage *musicImageSel = [UIImage imageNamed:@"musicSel.png"];

musicImage = [musicImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
musicImageSel = [musicImageSel imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

self.musicViewController.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"Music" image:musicImage selectedImage:musicImageSel];

@Rushabh,我需要更多的信息,你是从哪里调用它的?是从Appdelegate、viewController还是UITabbar/Controller子类或类别中? - gav
这仅适用于其中一张图片。使用此精确代码,未选定的选项卡项目看起来像我设置的图标。但是所选项目只是一个蓝色圆圈。 - Halsafar
我目前遇到了相同的问题,但只有在安装了iOS 7的非Retina设备上运行时才会出现。 - MusiGenesis
在iOS 7.1中,不需要这个解决方法。我想知道这是不是一个错误? - Kyokook Hwang
请注意,与更改UIImage渲染模式一起使用:imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal是一个非常重要的细节。如果您的图像被配置为模板,则会显示默认系统颜色。因此,尝试使用item.selectedImage = [someImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];而不是item.selectedImage = someImage;,看看是否有效。 - Alejandro Iván

56
将工具栏项图片的渲染模式设置为原始即可解决此问题。可以通过在.xcassets中使用图像来完成此操作,因此您不必编写大量代码。
第一步,将工具栏项图像拖放到Assets.xcassets中。
第二步,选择工具栏项图像,将[渲染方式]更改为[原始图像]。

enter image description here

PS:通常我会通过故事板设置TabBarController的选项卡条目,以避免编写大量代码。

enter image description here


1
更清晰的解决选项卡图像问题的方法。谢谢。 - Ratan
谢谢你,贾晓! - Marin
哇!!非常感谢。 - Anurag Sharma
那个答案必须被接受,因为没有必要编写代码来从StoryBoard中显示原始图像。伟大的人继续保持。 - Nitin Gohel

45

在代码中添加这些行

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
UITabBar *tabBar = tabBarController.tabBar;
UITabBarItem *tabBarItem1 = [tabBar.items objectAtIndex:0];
UITabBarItem *tabBarItem2 = [tabBar.items objectAtIndex:1];
UITabBarItem *tabBarItem3 = [tabBar.items objectAtIndex:2];
UITabBarItem *tabBarItem4 = [tabBar.items objectAtIndex:3];

tabBarItem1.selectedImage = [[UIImage imageNamed:@"selectimg"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
tabBarItem1.image = [[UIImage imageNamed:@"deselectimg"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
tabBarItem1.title = @"xxxx";

tabBarItem2.selectedImage = [[UIImage imageNamed:@"selectimg"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
tabBarItem2.image = [[UIImage imageNamed:@"deselectimg"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
tabBarItem2.title = @"xxxx";

tabBarItem3.selectedImage = [[UIImage imageNamed:@"selectimg"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
tabBarItem3.image = [[UIImage imageNamed:@"deselectimg"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
tabBarItem3.title = @"xxxx";

tabBarItem4.selectedImage = [[UIImage imageNamed:@"selectimg"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
tabBarItem4.image = [[UIImage imageNamed:@"deselectimg"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
tabBarItem4.title = @"xxxx";

return YES;
}

这对我起作用。


2
这对于iOS7很有效,只是提醒一下,在早期的SDK中方法[UIImage imageWithRenderingMode]不可用。 - JBlake
2
在iOS7上对我不起作用。无论是背景图像还是选项卡栏项目的图像都没有显示出来。 - Ans
谢谢!这个问题困扰了我两个小时...说明书上说要使用方法initWithTitle:image:selectedImage:...但对我根本不起作用!你的方法非常好。 - Josh Engelsma
在iOS 8及以上版本中表现良好。 - Rumin

16

没有答案解决了这个问题。主要原因是我的TabBarController不是我的RootViewController

对于Storyboards,我使用的解决方案是:点击我的UITabButton并为selectedImage添加运行时属性:

对于与UITabController相关联的每个不同视图都要这样做。


非常感谢您的回答! - Cesare

9

在尝试几个小时后,我终于解决了让自定义选项卡栏在iOS 6和7上都能正常工作的问题。以下是我的解决方案...

UITabBarController *tabBarController = (UITabBarController *)[[self window] rootViewController];

UITabBar *tabBar = tabBarController.tabBar;
UITabBarItem *tabBarItem1 = [tabBar.items objectAtIndex:0];
UITabBarItem *tabBarItem2 = [tabBar.items objectAtIndex:1];
UITabBarItem *tabBarItem3 = [tabBar.items objectAtIndex:2];
UITabBarItem *tabBarItem4 = [tabBar.items objectAtIndex:3];

tabBarItem1.title = @"Home";
tabBarItem2.title = @"Map";
tabBarItem3.title = @"Weather";
tabBarItem4.title = @"Info";

if ([[[UIDevice currentDevice] systemVersion] floatValue] < 7) {
    [tabBarItem1 setFinishedSelectedImage:[UIImage imageNamed:@"cyexplore_home_white.png"] withFinishedUnselectedImage:[UIImage imageNamed:@"cyexplore_home_black.png"]];
    [tabBarItem2 setFinishedSelectedImage:[UIImage imageNamed:@"cyexplore_cloud_white.png"] withFinishedUnselectedImage:[UIImage imageNamed:@"cyexplore_cloud_black.png"]];
    [tabBarItem3 setFinishedSelectedImage:[UIImage imageNamed:@"cyexplore_map_white.png"] withFinishedUnselectedImage:[UIImage imageNamed:@"cyexplore_map_black.png"]];
    [tabBarItem4 setFinishedSelectedImage:[UIImage imageNamed:@"cyexplore_info_white.png"] withFinishedUnselectedImage:[UIImage imageNamed:@"cyexplore_info_black.png"]];
} else {
    tabBarItem1.selectedImage = [[UIImage imageNamed:@"cyexplore_home_white"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
    tabBarItem1.image = [[UIImage imageNamed:@"cyexplore_home_black"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];

    tabBarItem2.selectedImage = [[UIImage imageNamed:@"cyexplore_cloud_white"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
    tabBarItem2.image = [[UIImage imageNamed:@"cyexplore_cloud_black"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];

    tabBarItem3.selectedImage = [[UIImage imageNamed:@"cyexplore_map_white"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
    tabBarItem3.image = [[UIImage imageNamed:@"cyexplore_map_black"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];

    tabBarItem4.selectedImage = [[UIImage imageNamed:@"cyexplore_info_white"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
    tabBarItem4.image = [[UIImage imageNamed:@"cyexplore_info_black"]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
}

UIImage* tabBarBackground = [UIImage imageNamed:@"tabbar.png"];
[[UITabBar appearance] setBackgroundImage:tabBarBackground];
[[UITabBar appearance] setSelectionIndicatorImage:[UIImage imageNamed:@"tabbar_selected.png"]];
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor blackColor], UITextAttributeTextColor, nil] forState:UIControlStateNormal];
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor], UITextAttributeTextColor, nil] forState:UIControlStateSelected];

8
如果您正在使用故事板,您需要在导航控制器中添加标识符:“custom”。 接下来:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Assign tab bar item with titles
    UITabBarController *tabBarController = (UITabBarController *)self.window.rootViewController;
    UITabBar *tabBar = tabBarController.tabBar;
    UITabBarItem *tabBarItem1 = [tabBar.items objectAtIndex:0];
    UITabBarItem *tabBarItem2 = [tabBar.items objectAtIndex:1];
    UITabBarItem *tabBarItem3 = [tabBar.items objectAtIndex:2];

    (void)[tabBarItem1 initWithTitle:nil image:[UIImage imageNamed:@"home.png"] selectedImage:[UIImage imageNamed:@"home_selected.png"]];
    (void)[tabBarItem2 initWithTitle:nil image:[UIImage imageNamed:@"home.png"] selectedImage:[UIImage imageNamed:@"home_selected.png"]];
    (void)[tabBarItem3 initWithTitle:nil image:[UIImage imageNamed:@"home.png"] selectedImage:[UIImage imageNamed:@"home_selected.png"]];

    // Change the tab bar background
    UIImage* tabBarBackground = [UIImage imageNamed:@"tabbar.png"];
    [[UITabBar appearance] setBackgroundImage:tabBarBackground];



    return YES;
}

这对我来说可行。


非常感谢。我在NavigationController中没有“custom”。 - Ricardo

3
你应该写入函数中:
UIImage* tab_image = [UIImage imageNamed:@"tab_image.png"];
UIImage* tab_image_selected = [UIImage imageNamed:@"tab_image_selected.png"];

tab_image = [tab_image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
tab_image_selected = [tab_image_selected imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];

self.tabBarItem.image = tab_image;
self.tabBarItem.selectedImage = tab_image_selected;

我希望你能够找到所需的帮助。


以防万一你不知道,你可以使用 markdown 来格式化你发布的代码片段。这有助于使你的问题/答案更加简明易读。此外,请确保你实际上回答了原帖作者的问题。 - brandonscript

3

我曾经遇到过与Xcode 6.0.1 (6A317)相同的问题,这似乎是Interface Builder的一个漏洞。不过,我通过在Interface Builder中保留选定图像为空,然后在我的每个视图控制器的viewDidLoad中插入以下代码来解决了这个问题:

[self.navigationController.tabBarItem setSelectedImage:[UIImage imageNamed:@"imagename-selected"]];

现在它运作良好,显示我的选定图像和全局色调掩模。


3

对我没有用的任何答案——我正在使用MonoTouch,但如果您设置UITabBarTintColor属性,那么将使用该颜色突出显示所选图像。 在obj c中,它可能是setTintColor函数。


1
谢谢您,jharr100,这解决了我的问题。 :) 我希望我能给这个点赞两次! - BruceHill

2
在你的第一个视图控制器的.h文件中,我添加了以下内容: @property (weak, nonatomic) IBOutlet UITabBarItem *mapViewTabBarItem; @property (weak, nonatomic) IBOutlet UITabBarItem *profileViewTabBarItem; @property (weak, nonatomic) IBOutlet UITabBarItem *notificationViewTabBarItem;
(注意,mapViewTabBarItem是通过ctrl拖动实际的标签栏项目到.h文件顶部的属性声明列表中进行链接的)
接下来,在同一视图控制器的.m文件中,在viewDidLoad中添加以下内容:
self.tabBarItem = [self.tabBarController.tabBar.items objectAtIndex:0];
_mapViewTabBarItem.selectedImage = [[UIImage imageNamed:@"@2x-map-icon-selected.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
self.tabBarItem.image = [[UIImage imageNamed:@"@2x-map-icon.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];

_profileViewTabBarItem = [self.tabBarController.tabBar.items objectAtIndex:1];
_profileViewTabBarItem.selectedImage = [[UIImage imageNamed:@"@2x-profile-icon-selected.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
_profileViewTabBarItem.image = [[UIImage imageNamed:@"@2x-profile-icon.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];

_notificationViewTabBarItem = [self.tabBarController.tabBar.items objectAtIndex:2];
_notificationViewTabBarItem.selectedImage = [[UIImage imageNamed:@"@2x-notifications-icon-selected.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];
_notificationViewTabBarItem.image = [[UIImage imageNamed:@"@2x-notifications-icon.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal ];

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