仅更改一种特定的 UITabBarItem 色调颜色

Posted

技术标签:

【中文标题】仅更改一种特定的 UITabBarItem 色调颜色【英文标题】:Change only one specific UITabBarItem tint color 【发布时间】:2014-07-23 18:31:44 【问题描述】:

众所周知,UITabBarController 中选定(或活动)项目的色调可以轻松更改,这里是一个示例:

myBarController.tabBar.tintColor = [UIColor redColor];

在这种情况下,tabBar 中的 any 选项卡栏项目一旦被激活,就会呈现红色。同样,这适用于该标签栏中的所有项。

同一栏中的其他标签栏项目之间的活动色调颜色如何不同?例如,一个项目在被选中时可能具有红色调,而另一项可能具有蓝色调。

我知道这可能可以通过重绘和子类化整个标签栏来解决。然而,这是我唯一需要的改变,而且这样做似乎有点过头了。我并没有试图以任何方式更改样式或项目的呈现方式,只是为了使不同项目之间的风格不同。

我在任何地方都没有看到任何与 ios 7 和 8 中的更新相关的问题的答案。

【问题讨论】:

请查看我的详细答案:***.com/questions/43002013/… 【参考方案1】:

有一个更简单的方法来做到这一点! 将此添加到 UITabBar Item 应该是另一种颜色的 ViewController

- (void) viewWillAppear:(BOOL)animated 
   // change tint color to red
   [self.tabBarController.tabBar setTintColor:[UIColor redColor]];
   [super viewWillAppear: animated];

将此插入其他 ViewControllers

- (void) viewWillAppear:(BOOL)animated 
   // change tint color to black
   [self.tabBarController.tabBar setTintColor:[UIColor blackColor]];
   [super viewWillAppear: animated];

我用它在每个 ViewController 中获得不同的 Tint 颜色 例如:[红色|黑色 |绿色 |粉红色]

【讨论】:

对于任何使用 swift 的人:tabBarController?.tabBar.tintColor = UIColor.redColor()【参考方案2】:

@element119 使用 swift 解决方案(给你们这些懒人):

extension UIImage 
    func tabBarImageWithCustomTint(tintColor: UIColor) -> UIImage 
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        let context: CGContextRef = UIGraphicsGetCurrentContext()

        CGContextTranslateCTM(context, 0, self.size.height)
        CGContextScaleCTM(context, 1.0, -1.0)
        CGContextSetBlendMode(context, kCGBlendModeNormal)
        let rect: CGRect = CGRectMake(0, 0, self.size.width, self.size.height)

        CGContextClipToMask(context, rect, self.CGImage)

        tintColor.setFill()
        CGContextFillRect(context, rect)

        var newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        newImage = newImage.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
        return newImage
    

我正在使用此代码将我的中间图标染成红色:

if let items = self.tabBar.items as? [UITabBarItem] 
    let button = items[1]
    button.image = button.image?.tabBarImageWithCustomTint(UIColor.redColor())

【讨论】:

SWIFT 2: CGBlendMode.Normal 而不是 kCGBlendModeNormal,感谢以上回答【参考方案3】:

我做了一些实验并基于this answer,找到了一种方法来做我想做的事情子类化 UITabBarItem 或 UITabBar!

基本上,这个想法是创建一个 UIImage 方法,该方法模仿 UITabBar 的色调遮罩行为,同时以其“原始”形式呈现它并避免使用本机色调遮罩。

你所要做的就是创建一个新的 UIImage 实例方法,它返回一个用我们想要的颜色遮罩的图像:

@interface UIImage(Overlay)
- (instancetype)tabBarImageWithCustomTint:(UIColor *)tintColor;
@end

@implementation UIImage(Overlay)

- (instancetype)tabBarImageWithCustomTint:(UIColor *)tintColor

    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);
    [tintColor setFill];
    CGContextFillRect(context, rect);
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    newImage = [newImage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
    return newImage;

@end

这是我发布的答案中代码的一个相当简单的版本,有一个例外 - 返回的图像将其渲染模式设置为始终原始,这确保不会应用默认的 UITabBar 掩码。现在,只需在编辑标签栏项目时使用此方法:

navController.tabBarItem = [[UITabBarItem alloc] initWithTitle:@"title" image:normal_image selectedImage:[selected_image tabBarImageWithCustomTint:[UIColor redColor]]];

不用说,selected_image 是从UIImage imageNamed: 得到的正常图像,[UIColor redColor 可以替换为任何想要的颜色。

【讨论】:

【参考方案4】:

这对我来说很好用!! Swift 3 的代码

extension UIImage 
    func tabBarImageWithCustomTint(tintColor: UIColor) -> UIImage 
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        let context: CGContext = UIGraphicsGetCurrentContext()!
        context.translateBy(x: 0, y: self.size.height)
        context.scaleBy(x: 1.0, y: -1.0)
        context.setBlendMode(CGBlendMode(rawValue: 1)!)
        let rect: CGRect = CGRect(x: 0, y: 0, width:  self.size.width, height: self.size.height)
        context.clip(to: rect, mask: self.cgImage!)
        tintColor.setFill()
        context.fill(rect)
        var newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        newImage = newImage.withRenderingMode(UIImageRenderingMode.alwaysOriginal)
        return newImage
    

之后……

 button.image = button.image?.tabBarImageWithCustomTint(tintColor: UIColor(red: 30.0/255.0, green: 33.0/255.0, blue: 108.0/255.0, alpha: 1.0))

谢谢 ;))

【讨论】:

【参考方案5】:

swift xcode7.1 测试:

extension UIImage 
    func tabBarImageWithCustomTint(tintColor: UIColor) -> UIImage 
        UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
        let context: CGContextRef = UIGraphicsGetCurrentContext()!

        CGContextTranslateCTM(context, 0, self.size.height)
        CGContextScaleCTM(context, 1.0, -1.0)
        CGContextSetBlendMode(context, CGBlendMode.Normal)
        let rect: CGRect = CGRectMake(0, 0, self.size.width, self.size.height)

        CGContextClipToMask(context, rect, self.CGImage)

        tintColor.setFill()
        CGContextFillRect(context, rect)

        var newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

        newImage = newImage.imageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)
        return newImage
    

修复了@Binsh 回答中的兼容性问题

【讨论】:

【参考方案6】:

斯威夫特 5:

extension UIImage 
    func tintWithColor(color: UIColor) -> UIImage? 
        UIGraphicsBeginImageContextWithOptions(size, false, UIScreen.main.scale)
        guard let context = UIGraphicsGetCurrentContext() else  return nil 
        
        context.scaleBy(x: 1.0, y: -1.0)
        context.translateBy(x: 0.0, y: -self.size.height)
        context.setBlendMode(.multiply)
        
        let rect = CGRect(origin: .zero, size: size)
        guard let cgImage = self.cgImage else  return nil 
        context.clip(to: rect, mask: cgImage)
        color.setFill()
        context.fill(rect)
        
        let newImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return newImage
        
    
    

【讨论】:

以上是关于仅更改一种特定的 UITabBarItem 色调颜色的主要内容,如果未能解决你的问题,请参考以下文章

单独的 UITabBaritem 色调颜色

如何更改特定 UITabBarItem 的背景 [关闭]

UITabBar 在 iOS7 上更改一个 UITabBarItem 的背景颜色

UISegmentedControl 值更改时如何仅更改文本颜色?

仅作为 UITabBarItem 的图像

如何只在几个部分中以编程方式更改UIImage的色调?