Skip to content
DeveloperMemos

onChange Deprecation in SwiftUI for iOS 17(Alternatives)

SwiftUI, iOS 17, onChange1 min read

With the release of iOS 17, Apple introduced significant changes to the onChange view modifier in SwiftUI. This article explores the deprecation of the traditional onChange(of:perform:) modifier and demonstrates how to use the new variations effectively.

onChange Usage Before iOS 17

In iOS versions prior to 17, onChange(of:perform:) was used to execute an action whenever a specified property changed. This was particularly useful for triggering UI updates in response to state changes. You could also use it like this to capture the previous value as well:

1.onChange(of: foo) { [foo] newValue in
2
3}

The core functionality of it hasn't really changed - just the syntax.

Adapting to the Changes in iOS 17

Deprecation Warning

Upon setting your app's minimum deployment target to iOS 17, Xcode will display a deprecation warning for the old onChange usage. The warning suggests using one of the two new forms of the modifier. You can still use the old usage and it will compile.

New Variations of onChange

Zero Parameter Closure

This variation is used when you don't need to know the previous value of the property. It is useful for cases where the action does not depend on how the value has changed.

Example:

1.onChange(of: someProperty) {
2 // Perform action without needing the old value
3}

Two Parameter Closure

When you need to access both the old and new values of the property, use this version. This is particularly useful for comparing changes or handling transitions.

Example:

1.onChange(of: someProperty, initial: true) { oldValue, newValue in
2 // Compare and act upon the oldValue and newValue
3}

Bonus: The initial Property

Both variations of onChange come with an initial boolean property. When set to true, the action also runs when the view initially appears, providing an opportunity for initial setup or adjustments. This is welcome enhancement - it just to kind of annoy me how onChange wouldn't trigger on `onAppear``.

Example:

1.onChange(of: someProperty, initial: true) { _, newValue in
2 // Action to perform on view appearance and subsequent changes
3}

Anyways, I hope this short guide helped you a bit with refactoring your codebase for iOS 17!