How to support tinted home screen widgets in iOS 18
Marking views to be rendered with colors, handling images and more.
Published: Sept. 8, 2024 Sponsored App StoreIf you are like me, perhaps you just now realize that iOS 18 offers the option to tint the icons and widgets with it. The widgets’ tinted look may range from okay to almost unusable without tweaks.
Thankfully, the “fix” isn’t that difficult. Once you know what to do, it is a matter of simply tweaking the tinted design. This blog post is intended as a quick start for supporting the tinted home screen “variant” and not a comprehensive overview.
To tell the system how we wish our widgets to be tinted, we need to use the widgetAccentable
modifier, which has existed since iOS 16 because of the lock screen widgets. This is great because it means we can start using it without custom extensions to handle backward compatibility unless you support older iOS versions with your widgets.
We need to look at our widgets, decide what should be tinted - meaning shown in the color the user selects- and then apply widgetAccentable
to all these views. And that’s it! The most basic support, I mean.
The good rule of thumb is to add the accentable modifier to any view that is normally displayed with color. Also, if you have just primary color text, then you may pick the most important one and make it accentable. For my countdown widgets in GamingBuddy that would be the number of days left until the game is released.
Important: In the docs, Apple mentions that once you set some view as widgetAccentable
, you cannot disable this for any of its subviews with .widgetAccentable(false)
.
More advanced stuff
I found that some views aren’t easily handled by just making them accentable. For example, if you have a button with a title and color background, the default accented look probably won’t look great…
We need to know whether the widget is in the accented rendering mode and if we need to do further customization. Thankfully there is @Environment
property for that:
@Environment(\.widgetRenderingMode) var widgetRenderingMode
With this, I was able to customize the background opacity to 0.2
when the rendering mode is accented to make the buttons look much nicer.
button
.background(backgroundColor.opacity(widgetRenderingMode == .accented ? 0.2 : 1))
And with that out of the way, there is one last part to know about - images. By default, the accented image is rendered using the tint color, which works great for icons or SF Symbols. However, it won't look great if you have more detailed images.
For handling these image cases, Apple added widgetAccentedRenderingMode
modifier. This is only available in iOS 18 and upwards and can be used to tweak how images are rendered in the accented mode.
You can specify four values:
accented
this will render the image in the accented uniform color, so only suitable for icons and something you can just get with thewidgetAccentable
.accentedDesaturated
will tint the image based on its luminance content, so it won’t lose details like withaccented
. I think in most cases this is what you want for images that aren’t simple icons.desaturated
will basically turn your image into black and white representation.fullColor
- as the name suggests, this will keep the image as is, basically ignoring the whole accentable thing. Although this might seem great for images, I suggest not using it unless you have a very good reason. The image then looks out of place among all the accented stuff; for example, Apple Photo’s widgets don’t even use it for the photos.