How to reload View in SwiftUI
In this tutorial, we will see the process of reloading views in SwiftUI using various data properties.
The SwiftUI views will be automatically updated when the data they depend on changes. This will make it easier to handle UI modifications compared to UIKit.
SwiftUI provides some data types that can enable automatic reloading or updating of views.
Understanding Data Types in SwiftUI
SwiftUI automatically updates views when a specific data type changes. These data types are implemented using a Swift feature called Property Wrappers, which are indicated by the @
prefix.
Here are some types of data that we can use to reload or update Views automatically in SwiftUI.
Using the @State Property Wrapper
Suppose we have a simple counter in our app. Now, we can use the @State
property wrapper to track changes to this counter and update the view accordingly.
So, when the counter changes, SwiftUI will automatically detect it and refresh the parts of our app that display the counter.
Example
import SwiftUI struct ContentView: View { // Declare a state variable named myCounter initialized to 0, this will use to trigger the view update. @State private var myCounter = 0 var body: some View { VStack (spacing: 20) { // Display text showing the current value of myCounter Text("Current Count: \(myCounter)") // Create a button with the text "Increment" Button("Increment") { // When the button is tapped, increment myCounter by 1 myCounter += 1 } } .font(.largeTitle) } }
Output:
Using @Binding property wrapper
We can basically use the @Binding
property wrapper when we need to pass data between parent and child views and any changes made in one view will instantly reflect in the other.
Now, suppose we have another view called DetailView
that also needs to know about the counter. We can use @Binding
to pass the counter value from the main view to the DetailView
.
Example
import SwiftUI // ChildView struct ChildView: View { // Binding variable to hold the counter value from the parent view. @Binding var childCounter: Int var body: some View { VStack { // Display the current value of the child counter. Text("Child Counter: \(childCounter)") // Button to increment the child counter. Button("Increment Child Counter") { childCounter += 1 } } .font(.title) .padding() } } // ParentView struct ParentView: View { // State variable to hold the counter value. @State private var parentCounter = 0 var body: some View { VStack { // Display the current value of the parent counter. Text("Parent Counter: \(parentCounter)") // Embed ChildView inside the parent view and pass the parentCounter as a binding. ChildView(childCounter: $parentCounter) } .font(.title) .padding() } }
Output:
As we can see in the output when we click the “Increment Child Counter” button to make changes in ChildView
, the parent view is automatically changed because of the @Binding
.
Using the @Published inside ObservableObject
Sometimes, we can have more complex data that needs to be shared across multiple views. In this case, we can create an ObservableObject
class.
This class contains the data that we want to observe for changes, and we use the @Published
property wrapper to mark properties that trigger the view updates.
Example
import SwiftUI // Define a class called DataModel that conforms to ObservableObject. class DataModel: ObservableObject { //Declare a property called myCounter with @Published property wrapper to update SwiftUI views as they changes. @Published var myCounter = 0 } struct ContentView: View { // Create an instance of DataModel and observe changes to it using @ObservedObject. @ObservedObject var dataModel = DataModel() var body: some View { // Define the body of the view. VStack (spacing: 20) { // Display the current value of myCounter. Text("Current Count: \(dataModel.myCounter)") // Create a button that increments the value of myCounter when tapped. Button("Increment") { // Update the value of myCounter by adding 1. dataModel.myCounter += 1 } } .font(.largeTitle) } }
Output:
Some additional data types
Except for these three data types I have mentioned above, SwiftUI provides several other data types that can trigger view updates.
Now, have a look below to see some additional data types that we can use to update views.
@ObservedObject
: This enables a view to observe and react to changes in an external object.@StateObject
: This is similar to@ObservedObject
, but it manages the life cycle of the observed object.@EnvironmentObject
: Provides a way to share data across views in the SwiftUI hierarchy.@Environment
: Retrieves values stored in the environment, such as color scheme or locale.@FetchRequest
: Automatically updates the view in response to changes in a Core Data fetch request.@AppStorage
: Reads and writes values to UserDefaults.@SceneStorage
: Stores values across app launches within a specific scene.
We can also use the above data types to update views. When we use this in our view, it will automatically update or reload to reflect changes.
Leave a Reply