Ryan Kanno
Ryan Kanno

Reputation: 115

SwiftUI onDisappear if statement not executing

I have a simple view that is not executing an if statement in the onDisappear and it's driving me mad. Have no idea why this is happening. As you can see with the print statements below, the Bool shouldUpdateStatus is clearly printing true, but it still doesn't enter the if statement. Any help would be appreciated. Currently using Xcode 15.3. Must tap button to show the alert, then tap the button in the alert.

struct DetailView: View {
   @State private var shouldUpdateStatus = false
   @State private var showAlert = false
   @Binding var path: NavigationPath

   var body: some View {
      Button {
         showAlert = true
      } label: {
         Text("Tap me")
      }
      .alert("Success!", isPresented: $showAlert) {
         Button("Dismiss", role: .cancel) {
            shouldUpdateStatus = true
            path = []
         }
      }
      .onDisappear {
         print("shouldUpdateStatus: \(shouldUpdateStatus)")
         // prints "shouldUpdateStatus: true"

         if shouldUpdateStatus {
            print("Did enter if statement")
            // this never executes
         }
      }
   }
}

EDIT

I added a didSet to the variable shouldUpdateStatus to print its value, and I see that indeed shouldUpdateStatus is being set to true. However I'm still having the same issue.

I also tried adding let _ = shouldUpdateStatus to the body, but also I see no changes.

Also tried adding other else if statements to check _shouldUpdateStatus.wrappedValue == true and $shouldUpdateStatus.wrappedValue == true, both of which are true, but those else if statements never execute either.

Upvotes: 0

Views: 158

Answers (2)

Here is my test code to show the if shouldUpdateStatus {...} in .onDisappear works. Let us know if this code does not work for you.

struct ContentView: View {
    @State private var path = NavigationPath()
    
    var body: some View {
        NavigationStack(path: $path) {
            Button("Go to destination") {
                path.append("destination")
            }
            .navigationDestination(for: String.self) { _ in
                DetailView(path: $path)
            }
        }
    }
}

struct DetailView: View {
   @State private var shouldUpdateStatus = false
   @State private var showAlert = false
   @Binding var path: NavigationPath

   var body: some View {
      Button {
         showAlert = true
      } label: {
         Text("Tap me")
      }
      .alert("Success!", isPresented: $showAlert) {
         Button("Dismiss", role: .cancel) {
            shouldUpdateStatus = true
            print("----> in Button: \(shouldUpdateStatus) ")
            path = NavigationPath()
         }
      }
      .onDisappear {
         print("--------> in onDisappear: \(shouldUpdateStatus) ")
         if shouldUpdateStatus {
            print("--------> in onDisappear did enter if statement")
         }
      }
   }
}

Upvotes: 0

malhal
malhal

Reputation: 30781

You forgot to call the @State getter in body so SwiftUI doesn't know you want a new version of the .onDisappear closure, you could hack it like this:

var body: some View {
    let _ = shouldUpdateStatus

But you should probably redesign you code and print it out in a didSet instead:


struct AlertConfig {
    var shouldUpdateStatus = false
    var showAlert = false {
        didSet {
             if !showAlert {
                 print("shouldUpdateStatus: \(shouldUpdateStatus)")
             }
        }
    }
}

struct DetailView: View {
   @State private var alertConfig = AlertConfig()
...
 .alert("Success!", isPresented: $alertConfig.showAlert) {

Upvotes: 0

Related Questions