Exploring the onChange Modifier in SwiftUI
In this article I will explain in simple terms how to use two swiftUI modifiers and when to use them.
Understanding OnChange Modifier
In SwiftUI, the onChange
modifier is used to make our app respond to changes in things like the screen or data we’re using. It’s like setting up a “watcher” to see when something changes. This can work with various things we’re watching, even if they are a bit more complex, as long as we can easily compare their values.
The onChange
modifier in SwiftUI is pretty easy to use. You tell it what you want to watch (like a string , integer or a boolean), and you also tell it what to do when that thing changes. That's it! It's like saying, "Hey, keep an eye on this, and when it changes, do this."
OnChange Syntax:
Before iOS 17 this is how onChange is written onChange(of:perform:)
.onChange(of: propertyToWatch) { newValue in
// Code to run when propertyToWatch changes to newValue
}
of:
keyword is used to specify the property or state variable you want to observe for changes. It tells SwiftUI what to “keep an eye on.”
perform:
keyword is followed by a closure (a block of code). This closure contains the actions you want to perform when the property you specified in of:
changes. It's where you define what should happen in response to the change.
newValue:
is the new value of the property when it changes.
What values can be Observed
Most of the time, it's used to watch data that's marked with @State
, @StateObject
, or @ObservableObject
. However, there are special cases where you can use it to watch other data, even if it's not the main focus of the view.
For optional values, you only need to worry about the type inside the optional being watchable. It’s like saying, “I’m watching this data, and I’ll act when it changes, whether it’s the main data or not.”
Lets try an example here using a TextField
. In this example want to watch the changes in the text entered by the user. Here's an example of how to use it:
import SwiftUI
struct ContentView: View {
@State private var text = ""
var body: some View {
TextField("Enter text", text: $text)
.onChange(of: text) { newValue in
print("Text changed to: \(newValue)")
}
}
}
In the example above :
We create a TextField
where the user can input text, and we bind it to the @State
property text
.
We use the onChange(of:perform:)
modifier with the text
property as the property to watch for changes.
Inside the closure, we specify what should happen when the text
property changes. In this case, we print the new value of the text to the console.
Whenever the user types something in the TextField
, the onChange
modifier will capture the change and execute the code in the closure.
Old value and New value:
Sometimes you might want to know both the old value and the new value of something you’re keeping an eye on. With this feature, you can easily get both of those values when the thing changes.
import SwiftUI
struct ContentView: View {
@State private var text = ""
@State private var previousText = ""
var body: some View {
VStack {
TextField("Enter text", text: $text)
.padding()
.border(Color.gray)
Text("Current Text: \(text)")
Text("Previous Text: \(previousText)")
}
.onChange(of: text) { newValue in
previousText = text
text = newValue
}
}
}
With this method, you can keep track of:
and show both the text that’s currently in the TextField
and the text that was there before. The onChange tool helps us notice when changes happen and make sure the right information is kept up to date.
limit text length:
The onChange
modifier in SwiftUI can be used to limit the length of text entered in a TextField
. This particular method can be handy when you want to restrict the user from entering more characters than allowed, for instance when your user is expected to enter their phone number, account number or password. Here's an example of how to use the onChange
modifier to limit text length in a TextField
:
import SwiftUI
struct ContentView: View {
@State private var text = ""
let characterLimit = 10 // Define the maximum character limit
var body: some View {
VStack {
TextField("Enter text", text: $text)
.padding()
.border(Color.gray)
}
.onChange(of: text) { newValue in
if newValue.count > characterLimit {
text = String(newValue.prefix(characterLimit))
}
}
}
}
In the example above, whenever the user enters text in the textfield, the onChange
modifier will be triggered. The onChange
modifier will then check the length of the text
state variable. If the length of the text
state variable is greater than 10, the onChange
modifier will truncate the string to the first 10 characters.
Conclusion
n this article, we’ve explored how to use the onChange
tool in SwiftUI. It's like having a watchful eye in your app, ready to react when things change, whether it's data or what the user does. It's simple to use; you just tell it what to watch and what to do when things change.
We’ve also shown real examples, like watching text changes or limiting how much text you can enter. These examples make your app more user-friendly and give you control.
Coming up next, we’ll dive into the onReceive
tool, which is like having a secret messenger for your data.