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
App Store

If 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 the widgetAccentable.

  • accentedDesaturated will tint the image based on its luminance content, so it won’t lose details like with accented. 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.

Bluesky logo

Follow on Bluesky to not miss new posts

Filip Němeček profile photo

WRITTEN BY

Filip Němeček Mastodon

iOS blogger and developer with interest in Python/Django.

iOS blogger and developer with interest in Python/Django.