Better Programming

Advice for programmers.

Follow publication

Implementing SwiftUI’s OnChange Modifier for iOS 13

Zane Carter
Better Programming
Published in
3 min readMar 16, 2021
Computer on desk
Photo by Patrick Ward on Unsplash.

With the release of iOS 14, SwiftUI gained some powerful new features. But if you're still stuck supporting iOS 13 platforms, then that doesn't do you much good, does it?

I recently needed to use the onChange view modifier in a project, but I soon came to realise that it’s not supported on iOS 13 deployment targets. Here’s the big fat error XCode gave me:

Error message

Fortunately, there is already a simple workaround for iOS 13. Have a look at this Picker I made below to select your favourite fruit:

Code snippet

Let’s say we wanted to print to the console whenever the selected fruit changes.

How would we achieve this?

Code snippet

We can actually use onReceive to listen to a given publisher, and of course, you can use onReceive Hooks dating back to as early as iOS 13.

But to create a Publisher that listens for changes to our selectedFruit variable, we have to wrap it in a Just publisher. Just is a built-in type of Publisher that just listens to changes to a given variable. You can test this out for yourself if you’d like. You can find the full code in this gist. And you can read up about Just publishers on Apple Developer.

Note: Just requires Combine, so make sure you use import Combine.

This doesn’t make things easy for you to implement across platforms, though. You still have to manually switch between onReceive and onChange using @available statements or just commit to use only the onReceive modifier instead.

To make things a bit easier for you, I made a custom onChange modifier that uses this onReceive under the hood for iOS 13. But if you end up compiling for an iOS 14 target, you can take full advantage of Apple’s own onChange modifier.

Below, you can see the definition of Apple’s onChange modifier fetched by right-clicking on an onChange and selecting Jump To Definition. You can test this out in XCode yourself if you’d like:

Definition in code snippet

As you might expect, there is an @available tag above the definition specifying that this is only available on iOS 14 or above. We’re going to make our own definition close to this with implementations for both iOS 13 and iOS 14. To avoid confusing the compiler, we’ll name our implementation slightly differently. Our new backward-compatible modifier will be called valueChanged.

The solution:

You can safely use this new valueChanged modifier in any project on iOS 13+. Once you end up compiling for an iOS 14 target, you can be sure that your project already takes advantage of Apple’s onChange modifier.

Thanks for reading.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Zane Carter
Zane Carter

Written by Zane Carter

I make apps for the AppStore. Currently working on an app that makes gardening easier. Twitter: @iamzanecarter

Responses (2)

Write a response