iOS 13 `withTintColor` not obeying the color I assign

后端 未结 1 430
死守一世寂寞
死守一世寂寞 2021-01-13 06:52

I find the behavior of the new iOS 13 UIImage property withTintColor(_:renderingMode:) incomprehensible. What is it for, and how does it relate to the tint colo

相关标签:
1条回答
  • 2021-01-13 07:21

    withTintColor is probably intended primarily for use only with symbol images, which are always treated as templates and have no color of their own. However, it is also very nice to be able to treat an ordinary image as a template and give it a color.

    Let's say you're drawing into a custom UIView's draw(_:) method, or drawing in a UIImageView graphics context. There has always been a problem with template views; you have no access here to their template behavior, so there is no way to tint them. withTintColor solves that problem.

    There is no doubt, however, that the behavior of these methods is profoundly weird when you use them in any other way:

    • As soon as you say withTintColor, the resulting image is treated as a template image, even if you say .alwaysOriginal. So your rendering mode is now being ignored!

    • Moreover, in contexts where there is already a tintColor, there can now be two competing tint colors: that of the context (the surrounding view or the inherited tintColor) and that of the image when you say withTintColor. And if this is a template image — a symbol image, or an .alwaysTemplate image, or an image in a template context like a button — then the context's tintColor wins, and the color that you specifically applied by saying withTintColor is ignored!!

    For example, this results in a blue symbol image (because the default image view tintColor is blue) even though you specifically set the symbol image's tint color to red:

    let im = UIImage(systemName:"circle.fill")?.withTintColor(.red)
    let iv = UIImageView(image:im)
    

    To get a red symbol image, you have to say this:

    let im = UIImage(systemName:"circle.fill")?.withTintColor(.red,
        renderingMode: .alwaysOriginal)
    

    So in the first code, the tint color you assign is being ignored (we get blue, not red), but in the second code, the rendering mode you assign is being ignored (it's still a template image, but now it's red as requested). Weird, eh?

    (I find it very hard to believe that this is the intended behavior, and I've filed a bug, but so far no response from Apple.)

    0 讨论(0)
提交回复
热议问题