SwiftUI: How can I pop to the root view for watchOS?

Viewed 536

I need to pop to the root view from a deep detail view. And while the following solution using isDetailLink and isActive works quite well for iOS, it does not work for watchOS. The isDetailLink command is unavailable in watchOS.

'isDetailLink' is unavailable in watchOS

import SwiftUI

class AppState : ObservableObject {
    @Published var showState : Bool = false
}

struct MoreTests: View {
    @EnvironmentObject var appState : AppState    // injected from SceneDelegate
    var body: some View {
        NavigationView {
            NavigationLink(
                destination: MoreView1(),
                isActive: $appState.showState,      // required to work
                label: { Text("Go to MoreView1") }
            ).isDetailLink(false)       // required to work
        }.navigationBarTitle("Root")
    }
}

struct MoreView1: View {
    var body: some View {
        NavigationLink(
            destination: MoreView2(),
            label: { Text("Go to MoreView2") }
        )
        .navigationBarTitle("MoreView1")
    }
}

struct MoreView2: View {
    var body: some View {
        NavigationLink(
            destination: MoreView3(),
            label: { Text("Go to MoreView3") }
        )
        .navigationBarTitle("MoreView2")
    }
}

struct MoreView3: View {
    @Environment(\.presentationMode) var presentationMode
    @EnvironmentObject var appState : AppState
    var body: some View {
        VStack {
            Button(action: {
                self.appState.showState = false       // required
            }) {
                Text("Dismiss to root")
            }
        }.navigationBarTitle("MoreView3")
    }
}

The iOS solution came from How can I pop to the Root view using SwiftUI?.

2 Answers

An alternative is to (re)set the id of the NavigationView

Replace AppState with

class AppState : ObservableObject {
    @Published var appID = UUID()
}

In MoreTests remove the isActive parameter and add this modifier right before setting the navigationBarTitle

NavigationView {...

}
.id(appState.appID)

In MoreView3 assign a new UUID to the appID

Button(action: {
    self.appState.appID = UUID()
}) {
    Text("Dismiss to root")
}

Fixed with Xcode 13.4 / watchOS 8.5

  1. Create Project from template.

  2. Just copy-pasted above code

  3. Commented .isDetailLink(false)

  4. Use MoreTests as content of scene

  5. Build & Run

Related