从SwiftUI的上下文菜单触发导航

时间:2019-07-31 07:39:45

标签: swiftui

我有一个List,其中的NavigationLink中包含NavigationView。 我知道要使用ContextMenu扩展视图,该视图包含一个元素,该元素显示导航堆栈中的另一个视图。

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)
                            )
                        }
                }
            })
        }
    }
}

在我的项目上正常点击的导航工作正常。但是,上下文菜单在Xcode 11 Beta 5中停止工作。我收到以下错误:`[[WindowServer] display_timer_callback:意外状态。

如何从上下文菜单中将新的视图推入导航堆栈?

1 个答案:

答案 0 :(得分:0)

一种方法是使用 NavigationLink(destination: Destination, isActive: Binding<Bool>, @ViewBuilder label: () -> Label),将标签作为隐藏在 EmptyView 中的 ZStack。然后,您将选择要导航到的元素并切换 contextMenu 内的 NavigationLink。这是一个完整的例子:

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()
    }
}