I am trying to get a context menu to navigate to another view using the following code
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")
}
}
}
The NavigationLink
within the VStack
works as expected and navigates to the edit view but I want to use a contextMenu
. Although the context menu displays the image, when I tap on it it doesn't navigate to the edit view, instead it just cancels the context menu.
I am doing this within a watch app but don't think that should make a difference, is there anything special I have to do with context menu navigation?
In Xcode 11.4 it's now possible to do this with sensible NavigationLink
buttons. Yay! ๐
.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")
}
}
I would use the isActive
variant of NavigationLink that you can trigger by setting a state variable. Apple documents this here
This variant of NavigationLink
is well fit for dynamic/programatic navigation.
Your .contextMenu
sets the state variable to true and that activates the NavigationLink
. Because you don't want the link to be visible, set the label
view to EmptyView
Here's an example, not identical to your post but hopefully makes it clear.
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")
}
}
}
This works on 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")
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With