iOS 13`withTintColor`不遵循我指定的颜色

时间:2019-11-14 22:42:07

标签: ios swift uiimage ios13

我发现新的iOS 13 UIImage属性withTintColor(_:renderingMode:)的行为令人难以理解。它的作用是什么,它与图像出现的上下文的色调颜色有什么关系?

例如:

let im = UIImage(systemName:"circle.fill")?.withTintColor(.red)
let iv = UIImageView(image:im)
iv.frame.origin = CGPoint(x: 100, y: 400)
self.view.addSubview(iv)

我说.red。但这是蓝色的:

enter image description here

很明显它是蓝色的,因为它的颜色来自周围环境的色彩。但是,给图像本身着色颜色有什么意义呢?

但是它变得更加奇怪。我将绘制自己的图像并为其赋予 色彩:

let sz = CGSize(width: 20, height: 20)
let im = UIGraphicsImageRenderer(size:sz).image { ctx in
    ctx.cgContext.fillEllipse(in:CGRect(origin:.zero, size:sz))
}.withTintColor(.red)
let iv = UIImageView(image:im)
iv.frame.origin = CGPoint(x: 100, y: 400)
self.view.addSubview(iv)

我说了.red,它是红色的:

enter image description here

什么导致不一致?

1 个答案:

答案 0 :(得分:1)

withTintColor可能主要仅用于与符号图像一起使用的符号图像,这些图像始终被视为模板,并且没有自己的颜色。但是,能够将普通图像作为模板并为其赋予颜色也是很好的。

比方说,您正在绘制到自定义UIView的draw(_:)方法中,或在UIImageView图形上下文中进行绘制。模板视图一直存在问题;您无法在此处访问其模板行为,因此无法着色它们。 withTintColor解决了这个问题。

但是,毫无疑问,当您以任何其他方式使用它们时,这些方法的行为极为奇怪:

  • 只要您说出withTintColor,即使您说出.alwaysOriginal,结果图像也被视为模板图像。因此,您的渲染模式现在被忽略了!

  • 此外,在已经有tintColor的上下文中,现在可以有两种竞争的色彩:上下文的色彩(周围的视图或继承的{{ 1}})和您说tintColor时图像的图像。并且如果这是 template 图像(符号图像或withTintColor图像,或模板上下文中的按钮之类的图像),则 context的 { {1}}获胜,您说出.alwaysTemplate您专门应用的颜色被忽略了!

例如,即使您将符号图像的色调颜色专门设置为红色,这也会产生蓝色符号图像(因为默认图像视图tintColor为蓝色)。

withTintColor

要获得红色符号图像,您必须这样说:

tintColor

因此,在第一个代码中,您分配的色彩被忽略(我们变成蓝色,而不是红色),但是在第二个代码中,您分配的渲染模式被忽略(它仍然是模板图像,但现在是根据要求红色)。奇怪吗?

(我很难相信这是预期的行为,并且我已经提交了一个错误,但到目前为止苹果没有任何回应。)