仅更改一个特定的UITabBarItem色调

时间:2014-07-23 18:31:45

标签: ios ios7 ios8 uitabbaritem

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

myBarController.tabBar.tintColor = [UIColor redColor];

在这种情况下,tabBar中的任何标签栏项目一旦激活就会有红色。同样,这适用于此标签栏中所有项目。

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

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

我没有看到任何与iOS 7和8中的更新相关的问题的答案。

6 个答案:

答案 0 :(得分:9)

有一种更简单的方法可以做到这一点! 将其添加到ViewController,其中UITabBar项应该是另一种颜色

- (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中获得不同的色调颜色 例如:[红色|黑色|绿色|粉红色]

答案 1 :(得分:3)

使用swift的@ element119解决方案(对你懒惰的人):

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())
}

答案 2 :(得分:2)

我做了一些实验并基于this answer,找到了一种方法来做我想要的而不用继承UITabBarItem或UITabBar!

基本上,我们的想法是创建一个UIImage方法,模仿UITabBar的色调遮罩行为,同时在其原始的#34;中呈现它。形成并避免使用原生色调面膜。

你所要做的就是创建一个新的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可以替换为任何人想要的颜色。

答案 3 :(得分:2)

这对我来说很好!!代码为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))

谢谢;))

答案 4 :(得分:0)

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回答中的兼容性错误

答案 5 :(得分:0)

迅速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
        
    }
    
}