6
votes

I have a List that contains NavigationLink inside a NavigationView. I know want to extend the view with a ContextMenu that contains an element that shows another view inside my navigation stack.

struct MainView: View {
    @State var elements = ["Hello", "World"]

    var body: some View {
        NavigationView {
            List(elements, id: \.self, rowContent: { element in
                NavigationLink(destination: PresentView(element: element)) {
                    Text(element)
                        .contextMenu {
                            NavigationLink(
                                "Edit",
                                destination: EditView(element: element)
                            )
                        }
                }
            })
        }
    }
}

The navigation for a normal tap on my item works fine. The context menu however stopped working in Xcode 11 Beta 5. I get the following error: `[WindowServer] display_timer_callback: unexpected state.

How would I push a new view on my navigation stack from a context menu?

1
Question is a few months old? Do you have a solution? I'm trying the same implementation -- not getting the same "display_timer_callback" error, but nonetheless, the navigation within the .contextMenu is not working.drewster
@drewster unfortunately not. I replaced the NavigationLink with simple buttons setting a state in my navigation view to push new views.jlsiewert

1 Answers

0
votes

One approach is to use NavigationLink(destination: Destination, isActive: Binding<Bool>, @ViewBuilder label: () -> Label), the label as an EmptyView hidden inside a ZStack. You would then select the element to navigate to and toggling the NavigationLink inside the contextMenu. Here is a full example:

Full Example

struct PresentView: View {
    let element: String

    var body: some View {
        Text(element)
    }
}

struct EditView: View {
    let element: String

    var body: some View {
        Text("EditView for \(element)")
    }
}

struct MainView: View {
    @State var elements = ["Hello", "World"]

    @State var elementToEdit: String?
    @State var isPresentedEditView = false

    var body: some View {
        NavigationView {
            ZStack {

                NavigationLink(
                    destination: elementToEdit == nil ? AnyView(EmptyView()) : AnyView(EditView(element: elementToEdit!)),
                    isActive: $isPresentedEditView) {
                        EmptyView()
                    }

                List(elements, id: \.self) { element in
                    NavigationLink(destination: PresentView(element: element)) {
                        Text(element)
                            .contextMenu {
                                Button("Edit") {
                                    elementToEdit = element
                                    isPresentedEditView.toggle()
                                }
                            }
                    }
                }
            }
        }
    }
}

struct ContentView: View {
    var body: some View {
        MainView()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}