I noticed that when I place a white or black UIImage into a UISegmentedControl it automatically color masks it to match the tint of the segmented control. I thought this was really cool, and was wondering if I could do this elsewhere as well. For example, I have a bunch of buttons that have a uniform shape but varied colors. Instead of making a PNG for each button, could I somehow use this color masking to use the same image for all of them but then set a tint color or something to change their actual color?


当前回答

斯威夫特3:

如果你已经通过xCode界面构建器设置了你的图像,这个解决方案可能会很舒服。基本上你有一个扩展来着色图像:

extension UIImage {
    public func image(withTintColor color: 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.normal)
        let rect: CGRect = CGRect(x: 0, y: 0, width: self.size.width, height: self.size.height)
        context.clip(to: rect, mask: self.cgImage!)
        color.setFill()
        context.fill(rect)
        let newImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()
        return newImage
    }
}

然后,你可以准备这个UIButton扩展为特定状态的图像上色:

extension UIButton {
    func imageWith(color:UIColor, for: UIControlState) {
        if let imageForState = self.image(for: state) {
            self.image(for: .normal)?.withRenderingMode(.alwaysTemplate)
            let colorizedImage = imageForState.image(withTintColor: color)
            self.setImage(colorizedImage, for: state)
        }
    }
}

用法:

myButton.imageWith(.red, for: .normal)

P.S.(在表格单元格中工作也很好,你不需要调用setNeedDisplay()方法,由于UIImage扩展,颜色的变化是立即的。

其他回答

以上都不适合我,因为点击后色调被清除。我必须使用

button.setImageTintColor(Palette.darkGray(), for: UIControlState())

你应该试试

设置好框架后

NSArray *arr10 =[NSArray arrayWithObjects:btn1,btn2,nil];
for(UIButton *btn10 in arr10)
{
CAGradientLayer *btnGradient2 = [CAGradientLayer layer];
btnGradient2.frame = btn10.bounds;

btnGradient2.colors = [NSArray arrayWithObjects:
                       (id)[[UIColor colorWithRed:151.0/255.0f green:206.0/255.5 blue:99.0/255.0 alpha:1] CGColor],
                       (id)[[UIColor colorWithRed:126.0/255.0f green:192.0/255.5 blue:65.0/255.0 alpha:1]CGColor],
                       nil];
[btn10.layer insertSublayer:btnGradient2 atIndex:0];

}

改变按钮图像或图像视图色调颜色

btn.imageView?.image = btn.imageView?.image?.withRenderingMode(.alwaysTemplate)

btn.imageView?.tintColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)

如果你在ios15之后到达这里,你使用的是新的UIButton。配置api,那么您可能需要通过imageColorTransformer来实现。

看起来是这样的:

configuration.imageColorTransformer = UIConfigurationColorTransformer { _ in .green }

为了方便,你可以创建一个扩展:

extension UIButton.Configuration {
    func imageColor(_ color: UIColor) -> UIButton.Configuration {
        var configuration = self
        configuration.imageColorTransformer = UIConfigurationColorTransformer { _ in color }
        return configuration
    }
}

// Usage:
configuration = configuration.imageColor(.green)

与其他答案一样,图像本身必须在Xcode资产中“渲染为模板图像”,或者在code image. withrenderingmode (.alwaysTemplate)中


小贴士: 如果您想在按钮高亮显示时改变图像颜色,该怎么办?然后你的配置扩展看起来像这样:

func imageColor(whenNormal: UIColor,
                whenHighlighted: UIColor,
                isHighlighted: Bool) -> UIButton.Configuration {
    var configuration = self
    configuration.imageColorTransformer = UIConfigurationColorTransformer { _ in
        isHighlighted ? whenHighlighted : whenNormal
    }
    return configuration
}

这个本身必须从configurationUpdateHandler上下文中调用,就像这样:

someButton.configurationUpdateHandler = { button in
    guard var configuration = button.configuration else {  return }
    configuration.image = UIImage(named: "some_image")
    configuration = configuration.imageColor(whenNormal: .green,
                                             whenHighlighted: .green.withAlphaComponent(0.7),
                                             isHighlighted: button.isHighlighted)
    button.configuration = configuration
}

注意,您还可以在configurationUpdateHandler中根据按钮状态定义不同的映像。

为了让tintColor影响UIImage,你必须将图像渲染模式设置为UIImageRenderingModeAlwaysTemplate。以下是Swift中的解决方案:

let image = UIImage(named: "image-name")
let button = UIButton()
button.setImage(image?.imageWithRenderingMode(UIImageRenderingMode.AlwaysTemplate), forState: .Normal)
button.tintColor = UIColor.whiteColor()

快4倍

button.setImage(image.withRenderingMode(UIImage.RenderingMode.alwaysTemplate), for: .normal)
button.tintColor = UIColor.blue