可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have an UITabBar with 5 items. I want to change the unselected color of all items. The items aren't declared in the UIViewController classes (i built them and linked the views in the Storyboard).
Is there an code like this : [[UITabBar appearance] set***UN***SelectedImageTintColor:[UIColor whiteColor]];
?
回答1:
SO says i cannot delete the accepted answer (i tried), but obviously, there are a lot of upvotes for comments that this doesn't work for iOS 7.
See the other answer below with many more upvotes, or the link in @Liam's comment to this answer.
for iOS 6 only
It should be as simple as this:
[[UITabBar appearance] setTintColor:[UIColor grayColor]]; // for unselected items that are gray
[[UITabBar appearance] setSelectedImageTintColor:[UIColor greenColor]]; // for selected items that are green
回答2:
This will not work under iOS 7 as far as I can say. In particular, tintColor of the tab bar will define the color of the selected tab, not of the unselected ones. If you want to change the default in iOS 7, it seems that you have to actually use different icons (in the color you like to have for unselected tabs) and set the color of the text.
This example should tint selected tabs to red and render others in green. Run this code in your TabBarController:
// set color of selected icons and text to red
self.tabBar.tintColor = [UIColor redColor];
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIColor redColor], NSForegroundColorAttributeName, nil] forState:UIControlStateSelected];
// set color of unselected text to green
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor greenColor], NSForegroundColorAttributeName, nil]
forState:UIControlStateNormal];
// set selected and unselected icons
UITabBarItem *item0 = [self.tabBar.items objectAtIndex:0];
// this way, the icon gets rendered as it is (thus, it needs to be green in this example)
item0.image = [[UIImage imageNamed:@"unselected-icon.png"] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
// this icon is used for selected tab and it will get tinted as defined in self.tabBar.tintColor
item0.selectedImage = [UIImage imageNamed:@"selected-icon.png"];
If you set the icon in the story board only, you can control the color of the selected tab only (tintColor). All other icons and corresponding text will be drawn in gray.
Maybe someone knows an easier way to adopt the colors under iOS 7?
回答3:
Extending @Sven Tiffe’s answer for iOS 7, you can get your code to automatically tint the unselected UITabBar images added in the storyboard. The following approach will save you having to create two sets of icon images (i.e. selected vs unselected) and having to programatically load them in. Add the category method imageWithColor: (see - How can I change image tintColor in iOS and WatchKit) to your project then put the following in your custom UITabBarController viewDidLoad method:
// set the selected colors
[self.tabBar setTintColor:[UIColor whiteColor]];
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys: [UIColor whiteColor], NSForegroundColorAttributeName, nil] forState:UIControlStateSelected];
UIColor * unselectedColor = [UIColor colorWithRed:184/255.0f green:224/255.0f blue:242/255.0f alpha:1.0f];
// set color of unselected text
[[UITabBarItem appearance] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:unselectedColor, NSForegroundColorAttributeName, nil]
forState:UIControlStateNormal];
// generate a tinted unselected image based on image passed via the storyboard
for(UITabBarItem *item in self.tabBar.items) {
// use the UIImage category code for the imageWithColor: method
item.image = [[item.selectedImage imageWithColor:unselectedColor] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
}
Create a Category called UIImage+Overlay and on UIImage+Overlay.m (extracted from this answer ) :
@implementation UIImage(Overlay)
- (UIImage *)imageWithColor:(UIColor *)color1
{
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(context, 0, self.size.height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetBlendMode(context, kCGBlendModeNormal);
CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
CGContextClipToMask(context, rect, self.CGImage);
[color1 setFill];
CGContextFillRect(context, rect);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
@end
回答4:
In iOS 10 and higher, there are 3 possible easy solutions:
A. Instance from code (Swift):
self.tabBar.unselectedItemTintColor = unselectedcolor
B. Instance from IB:
Add a Key Path: unselectedItemTintColor
of type: Color
C. Global appearance (Swift):
UITabBar.appearance().unselectedItemTintColor = unselectedcolor
回答5:
Translating user3719695's answer to Swift, which now uses extensions:
UIImage+Overlay.swift
extension UIImage {
func imageWithColor(color1: UIColor) -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
color1.setFill()
let context = UIGraphicsGetCurrentContext()
CGContextTranslateCTM(context, 0, self.size.height)
CGContextScaleCTM(context, 1.0, -1.0);
CGContextSetBlendMode(context, CGBlendMode.Normal)
let rect = CGRectMake(0, 0, self.size.width, self.size.height) as CGRect
CGContextClipToMask(context, rect, self.CGImage)
CGContextFillRect(context, rect)
let newImage = UIGraphicsGetImageFromCurrentImageContext() as UIImage
UIGraphicsEndImageContext()
return newImage
}
}
customTabBar.swift
override func viewDidLoad() {
super.viewDidLoad()
for item in self.tabBar.items! {
item.image = item.selectedImage?.imageWithColor(unselectedColor).imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
//In case you wish to change the font color as well
let attributes = [NSForegroundColorAttributeName: unselectedColor]
item.setTitleTextAttributes(attributes, forState: UIControlState.Normal)
}
}
回答6:
Swift version in iOS 10 and higher -
UITabBar.appearance().tintColor = UIColor.gray
UITabBar.appearance().unselectedItemTintColor = UIColor.gray
回答7:
I had to move the code into viewWillAppear
because in viewDidLoad
the images weren't set yet.
Swift 4 Translation
import Foundation
import UIKit
extension UIImage {
func with(color: UIColor) -> UIImage {
guard let cgImage = self.cgImage else {
return self
}
UIGraphicsBeginImageContextWithOptions(size, false, scale)
let context = UIGraphicsGetCurrentContext()!
context.translateBy(x: 0, y: size.height)
context.scaleBy(x: 1.0, y: -1.0)
context.setBlendMode(.normal)
let imageRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
context.clip(to: imageRect, mask: cgImage)
color.setFill()
context.fill(imageRect)
let newImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext();
return newImage
}
}
class MYTabBarController: UITabBarController {
let unselectedColor = UIColor(red: 108/255.0, green: 110/255.0, blue: 114/255.0, alpha: 1.0)
let selectedColor = UIColor.blue()
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Unselected state colors
for item in self.tabBar.items! {
item.image = item.selectedImage!.with(color: unselectedColor).withRenderingMode(.alwaysOriginal)
}
UITabBarItem.appearance().setTitleTextAttributes([.foregroundColor : unselectedColor], for: .normal)
// Selected state colors
tabBar.tintColor = selectedColor
UITabBarItem.appearance().setTitleTextAttributes([.foregroundColor : selectedColor], for: .selected)
}
}
回答8:
Referring to the answer from here: UITabBar tint in iOS 7
You can set the tint color for selected and unselected tab bar buttons like this:
[[UIView appearanceWhenContainedIn:[UITabBar class], nil] setTintColor:[UIColor redColor]];
[[UITabBar appearance] setSelectedImageTintColor:[UIColor greenColor]];
The first line sets the unselected color - red in this example - by setting the UIView's tintColor when it's contained in a tab bar. Note that this only sets the unselected image's tint color - it doesn't change the color of the text below it.
The second line sets the tab bar's selected image tint color to green.
回答9:
The new answer to do this programmatically as of iOS 10+ is to use the unselectedItemTintColor
API. For example, if you have initialized your tab bar controller inside your AppDelegate
, it would looks like the following:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
...
let firstViewController = VC1()
let secondViewController = VC2()
let thirdViewController = VC3()
let tabBarCtrl = UITabBarController()
tabBarCtrl.viewControllers = [firstViewController, secondViewController, thirdViewController]
// set the color of the active tab
tabBarCtrl.tabBar.tintColor = UIColor.white
// set the color of the inactive tabs
tabBarCtrl.tabBar.unselectedItemTintColor = UIColor.gray
...
}
回答10:
Swift 4 version (Without implicitly unwrapping Optionals) :
UIImage+Overlay.swift
import UIKit
extension UIImage {
func with(color: UIColor) -> UIImage? {
guard let cgImage = self.cgImage else {
return self
}
UIGraphicsBeginImageContextWithOptions(size, false, scale)
if let context = UIGraphicsGetCurrentContext() {
context.translateBy(x: 0, y: size.height)
context.scaleBy(x: 1.0, y: -1.0)
context.setBlendMode(.normal)
let imageRect = CGRect(x: 0, y: 0, width: size.width, height: size.height)
context.clip(to: imageRect, mask: cgImage)
color.setFill()
context.fill(imageRect)
if let newImage = UIGraphicsGetImageFromCurrentImageContext() {
UIGraphicsEndImageContext();
return newImage
}
}
return nil;
}
}
CustomTabBarController.swift
class CustomTabBarController: UITabBarController {
override func viewDidLoad() {
super.viewDidLoad()
if #available(iOS 10.0, *) {
self.tabBar.unselectedItemTintColor = UIColor.init(white: 1, alpha: 0.5)
} else {
// Fallback on earlier versions
if let items = self.tabBar.items {
let unselectedColor = UIColor.init(white: 1, alpha: 0.5)
let selectedColor = UIColor.white
// Unselected state colors
for item in items {
if let selectedImage = item.selectedImage?.with(color: unselectedColor)?.withRenderingMode(.alwaysOriginal) {
item.image = selectedImage
}
}
UITabBarItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor : unselectedColor], for: .normal)
// Selected state colors
tabBar.tintColor = selectedColor
UITabBarItem.appearance().setTitleTextAttributes([NSAttributedStringKey.foregroundColor : selectedColor], for: .selected)
}
}
UITabBarItem.appearance().setTitleTextAttributes([NSAttributedStringKey.font: UIFont(name: "overpass-light", size: 12)!, NSAttributedStringKey.foregroundColor: UIColor.white], for: UIControlState.normal)
}
}
回答11:
@JoeGalid's imageWithColor:
solution with Xamarin:
using CoreGraphics;
using UIKit;
namespace Example
{
public static class UIImageExtensions
{
public static UIImage ImageWithColor(this UIImage image, UIColor color)
{
UIGraphics.BeginImageContextWithOptions(image.Size, false, image.CurrentScale);
color.SetFill();
var context = UIGraphics.GetCurrentContext();
context.TranslateCTM(0, image.Size.Height);
context.ScaleCTM(1.0f, -1.0f);
context.SetBlendMode(CoreGraphics.CGBlendMode.Normal);
var rect = new CGRect(0, 0, image.Size.Width, image.Size.Height);
context.ClipToMask(rect, image.CGImage);
context.FillRect(rect);
var newImage = UIGraphics.GetImageFromCurrentImageContext() as UIImage;
UIGraphics.EndImageContext();
return newImage;
}
}
}
Then utilize it when setting up the tab bar items:
var image = UIImage.FromBundle("name");
barItem.Image = image.ImageWithColor(UIColor.Gray).ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal);
barItem.SelectedImage = image.ImageWithColor(UIColor.Red).ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
回答12:
Or just without coding. Swift 4, Xcode 10.1.
- Add
UITabBar
on your View Controller using Interface Builder.
- Select the added view in the left panel.
- Type
cmd + alt + 3
or just click Show the Identity Inspector
in the right panel.
- In section
User Defined Runtime Attributes
click on plus button to add a new attribute and call it as unselectedItemTintColor
(see here).
- Without leaving the section from the previous step (see number 4) under
Type
column choose Color
type.
- Finally, set the necessary color under
Value
section.
- Compile your project
- Over. Congratulations.