Skip to content

πŸ‘©πŸ»β€πŸ’» πŸ§‘πŸ½β€πŸ’» Subscribe and Read us on Substack to Get Full Access to Our Posts


SwiftUI View Lifecycle: A Guide to onAppear, onDisappear, and Task

In this tutorial, we’ll explore the lifecycle events onAppear, onDisappear, and the asynchronous task modifier in SwiftUI. These tools are crucial for managing view states and performing actions at key points in a view’s lifecycle or asynchronously loading data when a view appears. Let’s dive into each of these with clear examples and see how they enhance the functionality of a SwiftUI app.

Understanding onAppear and onDisappear

onAppear and onDisappear are modifiers that you attach to views to perform actions when the views appear or disappear from the screen. They are particularly useful for starting or stopping processes that should only run when a view is visible to the user.

Example: Stopwatch

Imagine a simple stopwatch app. We use onAppear to start the timer when the view comes into focus and onDisappear to pause the timer when the user navigates away.

struct StopwatchView: View {
    
    @State private var secondsElapsed = 0
    @State private var timer: Timer?
    
    @State private var showView = false
    
    var body: some View {
        
        Button("Show View") {
            showView = true
               }
        .popover(isPresented: $showView) {
                 
            VStack {
                Text("Time: \(secondsElapsed) seconds")
                    .font(.largeTitle)
                    .padding()
                Button("Reset") {
                    secondsElapsed = 0
                }
            }
            .onAppear {
                print(".onAppear fired")
                timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
                    secondsElapsed += 1
                }
            }
            .onDisappear {
                print(".onDisappear fired")
                timer?.invalidate()
                timer = nil
                secondsElapsed = 0
                
            }        
        }
    }
}

In this StopwatchView, the timer starts counting when the view appears and stops counting when it disappears, preventing unnecessary resource usage.

Understanding task

The task modifier is used for performing asynchronous operations that are linked to a view’s lifecycle. It’s especially useful when you need to load data from external sources as soon as the view appears.

Example: Posts Data Fetcher

Here’s a simple view that fetches posts data asynchronously when it appears on the screen:

struct Post: Codable {
    let userID, id: Int
    let title, body: String

    enum CodingKeys: String, CodingKey {
        case userID = "userId"
        case id, title, body
    }
}

typealias Posts = [Post]


struct PostsView: View {
   
    @State private var requestInfo = "Loading weather data..."

    var body: some View {
        Text(requestInfo)
            .padding()
            .task {
                await loadDataFromServer()
            }
    }

    func loadDataFromServer() async {
        do {
            let url = URL(string: "https://jsonplaceholder.typicode.com/posts")!
            let (data, _) = try await URLSession.shared.data(from: url)
            let posts = try? JSONDecoder().decode(Posts.self, from: data)
            requestInfo = "The first post title:\n\(posts?.first?.title ?? "Nothing found")\n\nThe last post title:\n\(posts?.last?.title ?? "Nothing found")"
        } catch {
            requestInfo = "Failed to load data"
        }
    }
    
}

This PostsView initiates an asynchronous task to fetch data when the view appears. Using task, we ensure that the network request is automatically canceled if the view disappears before the request completes, thus handling resources efficiently.

Conclusion

Understanding and effectively utilizing onAppear, onDisappear, and task in SwiftUI are fundamental in creating responsive and efficient iOS apps. These tools allow to control the execution of code based on the visibility of views and manage asynchronous operations in a way that is tightly integrated with the view’s lifecycle. This approach ensures that your app behaves predictably and conservatively uses resources, enhancing the user experience.

 

 

 

Back To Top
Search