SwiftUI ContextMenu导航到另一个视图

时间:2019-10-07 14:20:48

标签: swiftui

我正在尝试使用以下代码获取上下文菜单以导航到另一个视图

var body: some View
{
    VStack
    {
        Text(self.event.name).font(.body)
        ...
        Spacer()
        NavigationLink(destination: EditView(event: self.event))
        {
            Image(systemName: "pencil")
        }
    }
    .navigationBarTitle(Text(appName))
    .contextMenu
    {
        NavigationLink(destination: EditView(event: self.event))
        {
            Image(systemName: "pencil")
        }
    }
}

NavigationLink中的VStack可以正常工作,并导航到编辑视图,但是我想使用contextMenu。尽管上下文菜单显示了图像,但是当我点击它时,它不会导航到编辑视图,而是取消了上下文菜单。

我正在手表应用程序中执行此操作,但不认为这会有所作为,上下文菜单导航有什么特别之处吗?

4 个答案:

答案 0 :(得分:2)

在Xcode 11.4中,现在可以通过明智的NavigationLink按钮来做到这一点。好极了! ?

.contextMenu {
    NavigationLink(destination: VisitEditView(visit: visit)) {
        Text("Edit visit")
        Image(systemName: "square.and.pencil")
    }
    NavigationLink(destination: SegmentsEditView(timelineItem: visit)) {
        Text("Edit individual segments")
        Image(systemName: "ellipsis")
    }
}

答案 1 :(得分:1)

我将使用NavigationLink的isActive变体,您可以通过设置状态变量来触发它。 Apple documents this here

NavigationLink的变体非常适合动态/程序化导航。

您的.contextMenu将状态变量设置为true,并激活NavigationLink。因为您不希望链接可见,所以将label视图设置为EmptyView

这是一个示例,与您的帖子并不相同,但希望可以清楚地说明。

struct ContentView: View {

    @State private var showEditView = false

    var body: some View {

        NavigationView {
            VStack {
                Text("Long Press Me")
                    .contextMenu {
                        Button(action: {
                            self.showEditView = true
                        }, label: {
                            HStack {
                                Text("Edit")
                                Image(systemName: "pencil")
                            }
                        })
                }
                NavigationLink(destination: Text("Edit Mode View Here"), isActive: $showEditView) {
                    EmptyView()
                }
            }
            .navigationBarTitle("Context Menu")
        }
    }
}

答案 2 :(得分:0)

这适用于Xcode 11.6

struct ContentView: View {
    
    @State var isActiveFromContextMenu = false
    var body: some View {
        NavigationView{
            VStack{
                NavigationLink(destination : detailTwo(), isActive: $isActiveFromContextMenu ){
                    EmptyView()
                }
                
                List{
                    NavigationLink(destination: detail() ){
                        row(isActiveFromContextMenu: $isActiveFromContextMenu)
                    }
                    NavigationLink(destination: detail() ){
                        row(isActiveFromContextMenu: $isActiveFromContextMenu)
                    }
                    NavigationLink(destination: detail() ){
                        row(isActiveFromContextMenu: $isActiveFromContextMenu)
                    }
                }
            }       
        }   
    }    
}

struct detail: View {
    var body: some View{
        Text("Detail view")
    }
}

struct detailTwo: View {
    var body: some View{
        Text("DetailTwo view")
    }
}

struct row: View {
    
    @Binding var isActiveFromContextMenu : Bool
    var body: some View {
        
        HStack{
            
            Text("item")
            
        }.contextMenu{
            Button(action: {
                self.isActiveFromContextMenu = true
            })
            {
                Text("navigate to")
            }
        }
    }
}

答案 3 :(得分:0)

我发现在后台屏蔽 NavigationLink 并使用 Button 切换上下文作为最短但最简单的替代方法取得了成功。

struct ContentView: View {
    @State private var isShowing = false

    var body: some View {
        NavigationView {
            Text("Hello")
                .background(NavigationLink("", destination: Text("World!"), isActive: $isShowing))
                .contextMenu {
                    Button {
                        isShowing = true
                    } label: {
                        Label("Switch to New View", systemImage: "chevron.forward")
                    }
                }
        }
    }
}