我发现新的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
。但这是蓝色的:
很明显它是蓝色的,因为它的颜色来自周围环境的色彩。但是,给图像本身着色颜色有什么意义呢?
但是它变得更加奇怪。我将绘制自己的图像并为其赋予 色彩:
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
,它是红色的:
什么导致不一致?
答案 0 :(得分:1)
withTintColor
可能主要仅用于与符号图像一起使用的符号图像,这些图像始终被视为模板,并且没有自己的颜色。但是,能够将普通图像作为模板并为其赋予颜色也是很好的。
比方说,您正在绘制到自定义UIView的draw(_:)
方法中,或在UIImageView图形上下文中进行绘制。模板视图一直存在问题;您无法在此处访问其模板行为,因此无法着色它们。 withTintColor
解决了这个问题。
但是,毫无疑问,当您以任何其他方式使用它们时,这些方法的行为极为奇怪:
只要您说出withTintColor
,即使您说出.alwaysOriginal
,结果图像也被视为模板图像。因此,您的渲染模式现在被忽略了!
此外,在已经有tintColor
的上下文中,现在可以有两种竞争的色彩:上下文的色彩(周围的视图或继承的{{ 1}})和您说tintColor
时图像的图像。并且如果这是 template 图像(符号图像或withTintColor
图像,或模板上下文中的按钮之类的图像),则 context的 { {1}}获胜,您说出.alwaysTemplate
的您专门应用的颜色被忽略了!
例如,即使您将符号图像的色调颜色专门设置为红色,这也会产生蓝色符号图像(因为默认图像视图tintColor
为蓝色)。
withTintColor
要获得红色符号图像,您必须这样说:
tintColor
因此,在第一个代码中,您分配的色彩被忽略(我们变成蓝色,而不是红色),但是在第二个代码中,您分配的渲染模式被忽略(它仍然是模板图像,但现在是根据要求红色)。奇怪吗?
(我很难相信这是预期的行为,并且我已经提交了一个错误,但到目前为止苹果没有任何回应。)