5

Wondering if anyone else has this issue, and if a workaround has been found. This works fine in iOS 13, but seems broken in iOS 14. I am just trying to fire off a NavigationLink to another View, from a .contextMenu.

My code is as below.

import SwiftUI

struct ContentView: View {
    var body: some View {
        
        NavigationView {
            VStack {
                HStack {
                    Text("I am a text in a HStack ")
                }
                HStack {
                    NavigationLink(destination: TestView()) {
                        VStack {
                            Image(systemName:"gauge")
                                .font(.system(size: 31))
                        }
                    }
                }
            }
            .contextMenu {
                NavigationLink(destination: TestView()) {
                    Text("Navigate to TestView")
                    Image(systemName: "pencil")
                }
            }
        }
    }
}

The Destination TestView() is just a boilerplate "Hello World" view.

If I click not the Icon associated in the Stack, this triggers the navigation perfectly. But the same link in the context menu does not. When I select it in the contextmenu, nothing happens. I.e I can select the menu item, but all it does is close the context menu and I stay on the same view.

Anyone else found this? solved it ? Thanks

CalinOz
  • 65
  • 3
  • I think it was a bug. I would not expected NavigationLink would work outside of NavigationView, but contextMenu is really a different view hierarchy. Use NavigationLink inside NavigationView (say in invisible in background) and activate programmatically from contextMenu. Similarly to next approach https://stackoverflow.com/a/61181490/12299030 – Asperi Aug 04 '20 at 11:27

1 Answers1

1

Here is a demo of possible approach. Tested with Xcode 12b3 / iOS 14 (also valid for SwiftUI 1.0)

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

    var body: some View {

        NavigationView {
            VStack {
                HStack {
                    Text("I am a text in a HStack ")
                }
                HStack {
                    NavigationLink(destination: Text("TestView")) {
                        VStack {
                            Image(systemName:"gauge")
                                .font(.system(size: 31))
                        }
                    }
                }
            }
            .background(NavigationLink("", destination: Text("TestView"), isActive: $showLink))
            .contextMenu {
                Button(action: { self.showLink = true }) {
                    HStack {
                        Text("Navigate to TestView")
                        Image(systemName: "pencil")
                    }
                }
            }
        }
    }
}
Asperi
  • 228,894
  • 20
  • 464
  • 690
  • 1
    Many thanks for the reply and the proposed approach - it also works on Xcode 12b4. That said it could get messy when you have a number of contextMenu items. Shame that something that worked so well in iOS13 does not seem to in iOS 14. Thanks – CalinOz Aug 05 '20 at 01:09
  • In case of many menu items you can use similarly one background NavigationLink but initialised with tag and selection, so every menu item activates selection, which can be enum and even change destination based on that enum... so... life is not so bad :) – Asperi Aug 05 '20 at 03:59