SwiftUI NavigationView, возврат, если NavigationLink находится внутри NavigationBarItem

Поскольку есть некоторые проблемы с iOS 13.4 и Xcode 11.4 с presentationMode.wrappedValue.dismiss(), я ищу альтернативный подход для программного возврата. Я нашел это решение от MScottWaller:

iOS SwiftUI: программно отображать или закрывать представление

К сожалению, в моем случае это не работает:

struct MasterView: View {
    @State private var showDetail = false

    var body: some View {
        VStack {
            Text("MasterView")
            .navigationBarItems(trailing: HStack {
                NavigationLink(destination: DetailView(showSelf: $showDetail), isActive: $showDetail) {
                    Image(systemName: "tag")
                        .padding(.leading, 4)
                }
            })
        }
    }
}

struct DetailView: View {
    @Binding var showSelf: Bool

    var body: some View {
        Button(action: {
            self.showSelf = false
        }) {
            Text("Pop")
        }
    }
}

Если NavigationLink находится внутри navigationBarItem, я не могу вернуться из своего DetailView. Я не знаю, является ли это ошибкой или есть другие причины, по которым NavigationLink не работает таким же образом внутри navigationBarItem.

В качестве обходного пути я использую этот вариант с пустой ссылкой NavigationLink внутри представления. Работает, но мне это не нравится:

struct MasterView: View {
    @State private var showDetail = false

    var body: some View {
        VStack {
            Text("MasterView")
            NavigationLink(destination: DetailView(showSelf: $showDetail), isActive: $showDetail) {
                EmptyView()
            }
            .navigationBarItems(trailing: HStack {
                Button(action: { self.showDetail.toggle() }) {
                    Image(systemName: "tag")
                        .padding(.leading, 4)
                }
            })
        }
    }
}

Есть идеи, почему NavigationLink не работает внутри navigationBarItem?


person Babelfish    schedule 06.02.2020    source источник
comment
ты тестируешь на реальном устройстве?   -  person Jawad Ali    schedule 06.02.2020
comment
Насколько я понимаю NavigationView/NavigationLink описание API (и реальные наблюдения за поведением), последний должен находиться в иерархии стека навигации, тогда как NavigationBar находится выше стека навигации.   -  person Asperi    schedule 06.02.2020
comment
Вы уверены, что использование NavigationLink внутри navigationBarItems является подходящим или поддерживаемым вариантом использования?   -  person user3441734    schedule 06.02.2020
comment
@Asperi Это возможно, но почему NavigationLink вообще работает в NavigationBar?   -  person Babelfish    schedule 06.02.2020


Ответы (1)


Это ошибка iOS.

https://forums.developer.apple.com/thread/125937

Чтобы обойти эту проблему, нужно переключить NavigationLink, скрытую за пределами панели навигации:

 struct Parent: View {  

    @State private var showingChildView = false  

    var body: some View {  
        NavigationView {  
            VStack {  
                Text("Hello World")  
                NavigationLink(destination: Child(),  
                               isActive: self.$showingChildView)  
                { Text("HiddenLink").hidden() }
            }  
            .navigationBarItems(trailing: Button(action:{ self.showingChildView = true }) { Text("Next") })  
        }  
    }  
}  
person zavidovych    schedule 10.06.2020