UIImage RenderingMode iOS Development/ETC2024. 11. 16. 20:02
1. Intro
: 몇달 전 이야기입니다. 저는 공부하는 차원에서 만들고있는 iOS App이 있는데요. 기능도 적고, Spec도 아주 단순한 App이어서 iOS 18에서도 별다른 문제가 없을 줄 알았었어요.
돋보기 icon이 iOS 18부터는 다른 색상으로 표시되고 있네요. 저는 아래와 같은 code로 돋보기 icon을 노출시키고 있었습니다.
1
2
3
|
let icon = UIImage(systemName: "magnifyingglass")
icon.withTintColor(UIColor(Color.grau).withAlphaComponent(0.6),
renderingMode: .alwaysOriginal)
|
cs |
renderingMode를 alwaysOriginal로 적용했네요. 별도의 tintColor를 적용하면서 alwaysTemplate로 적용하게 작성했었던 것 같은데 실수했었나 봅니다. alwaysTemplate을 적용하도록 수정함으로써 이 문제는 쉽게 해결되었습니다.
해결하고보니 문득 생각이 들었습니다. 저는 renderingMode에 대해 얼마나 알고 있을까요? renderingMode에 적용할 수 있는 automatic, alwaysOriginal, alwaysTemplate의 차이에 대해 설명할 수 있을까요? 이번 기회에 정리해보면 좋겠다고 생각하여 정리해보았습니다.
2. UIImage.RenderingMode
: renderingMode는 color 정보를 이용해서 image를 어떻게 나타낼지를 조절하는 mode입니다. 총 3가지가 있는데, 각각은 다음과 같습니다.
automatic
: image 속성에 따라 template 또는 original로 rendering. 여기서 말하는 image 속성은 어떤 것을 말하는 것일까요?
`Render As` 부분에서 적용할 수 있는 image 속성입니다. original이나 template은 알겠는데, default는 뭘까요? default로 적용하게 되면 image가 어떤 context로 사용되는 지에 따라 `Render As Original Image`로 적용될수도, `Render As Template Image`로 적용될수도 있습니다. 몇가지 case를 정리해보죠.
1) UIImageView : `Render As Default` => `Render As Original Image`
2) UIButton : `Render As Default` => `Render As Template Image`
3) UITabBarItem : `Render As Default` => `Render As Template Image`
4) UINavigationItem : `Render As Default` => `Render As Template Image`
button이나 그와 유사한 곳에서 image를 rendering하는 경우 `Render As Default`는 `Render As Template Image`가 된다 정도로 정리할 수 있겠네요.
여담이지만, 저는 alwaysTemplate을 적용하도록 수정하여 문제를 해결했었는데요. 해당 image는 UISearchBar에 rendering되는데, 이건 `button이나 그와 유사한 곳`에 속하는 case여서 그냥 tintColor만 적용(renderingMode는 automatic)해도 됩니다.
alwaysOriginal
: image의 원본 그대로 rendering.
alwaysTemplate
: image가 갖고있는 color 정보는 무시되고, tintColor에 따라 color가 변경되어 rendering.
3. tintColor를 template image에 적용하는 Mechanism
: `Render As Template Image`로 설정된 image이거나 renderingMode가 alwaysTemplate인 경우, tintColor에 따라 image의 color가 변경되어 rendering 될 수 있습니다. 그런데 image의 각 pixel마다 RGB 값이나 Alpha 값이 다를텐데요, 어떤 기준으로 각 pixel에 tintColor를 적용하는 것일까요? Alpha 값이 0이냐 아니냐에 따라 tintColor가 적용되는 방식이 달라집니다.
불투명한 pixel (Alpha > 0)
: tintColor의 RGB 값이 적용되고, Alpha 값은 유지됩니다.
투명한 pixel (Alpha == 0)
: tintColor의 RGB 값이 적용되지 않습니다.
template image를 rendering할 때, tintColor를 명시하지 않으면 어떤 color가 적용될까요? UIImage에 renderingMode를 alwaysTemplate으로 적용하고, tintColor는 적용하지 않을 수도 있습니다.
1
|
let icon = UIImage(systemName: "magnifyingglass")?.withRenderingMode(.alwaysTemplate)
|
cs |
image에 tintColor를 적용하지 않았다면, 부모 View의 tintColor가 적용되게 됩니다. 만약 부모 View에도 tintColor가 적용되어 있지 않았다면 tintColor가 적용된 부모 View를 찾다가, 끝내 찾지 못한다면 System Blue Color가 적용되게 됩니다.
4. SwiftUI와 RenderingMode
: UIKit의 UIImage와 비슷합니다. tintColor 대신에 foregroundColor를 적용한다는 차이만 있습니다.
1
2
3
|
Image(systemName: "magnifyingglass")
.renderingMode(.template)
.foregroundColor(.gray)
|
cs |
5. Reference
1) https://developer.apple.com/documentation/uikit/uiimage/renderingmode
'iOS Development > ETC' 카테고리의 다른 글
UIAlertController에 TextField 추가시 [LayoutConstraints] warning (0) | 2022.10.28 |
---|---|
Xcode Build Setting에서 Other Linker Flag의 -ObjC는 무엇일까? (0) | 2020.09.27 |
간단하게 살펴보는 Unicode - 2) Swift String과 NSString (0) | 2020.04.06 |
간단하게 살펴보는 Unicode - 1) 소개 및 용어정리 (0) | 2020.01.19 |
UIView bounds vs frame (1) | 2019.12.07 |