将导航栏中的NavigationLink的目标强制为辅助/详细视图

时间:2019-08-31 01:02:53

标签: swiftui

我正在尝试在SwiftUI中,特别是在iPad上重现UISplitViewController的行为。此SwiftUI代码的行为不符合我的预期:

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                Text("Master")
            }.navigationBarItems(trailing: NavigationLink(destination: DetailView()) {
                Image(systemName: "plus")
            }).navigationBarTitle("Master List")
            Text("")
        }
    }
}

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

在iPhone设备上,它可以按预期工作。轻按导航栏中的加号按钮会将DetailView推入导航堆栈,一切似乎都很好。

在iPad上,加号会将详细信息视图推送到 master 视图中的导航堆栈上。即使我明确告诉它链接应使用isDetailLink(true)定位细节,它也会这样做。

还是我会以错误的方式处理这个问题?

(这遗留了一个次级问题,即如何避免在点击目标View之前对其进行评估。当目标视图接受参数(例如,空模型)并创建该模型时,这是理想的具有副作用(例如,将对象插入托管对象上下文中。This blog很好地说明了这种情况。)

2 个答案:

答案 0 :(得分:3)

请注意,在横向放置(https://stackoverflow.com/a/57345540/7786555)的大型iPhone上也会遇到相同的问题

isDetailLink(true)应该起作用(我认为)。这可能是影响导航栏的错误。我已经看到了许多奇怪的行为。似乎您在导航栏中放置的内容都失去了某种上下文。

到目前为止,我发现的解决方法是使用导航栏的动作来触发“主”视图中的某些内容。在这种情况下,NavigationLink现在位于主视图中(尽管不可见)。请注意,我将其放在.background()内,因此它不会影响其他视图的布局。

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

    var body: some View {
        NavigationView {

            VStack {
                Text("Master")
                    .background(NavigationLink(destination: DetailView(), isActive: $push) { EmptyView() })
            }.navigationBarItems(trailing:
                Button(action: { self.push = true }, label: {
                    Image(systemName: "plus")
                })
            ).navigationBarTitle("Master List")

            Text("")
        }
    }
}

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

最后,请注意,NavigationLink中有一个错误也会影响您。幸运的是,也有一种解决方法:SwiftUI: NavigationDestinationLink deprecated

答案 1 :(得分:0)

NavigationLink必须位于List内,请尝试以下操作:

import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            List {
                NavigationLink(destination: DetailView()){
                    Text("Show Detail")
                }
            }.navigationBarTitle("Master")
        }
    }
}

struct DetailView: View {
    var body: some View {
        Text("Detail Label").navigationBarTitle("Detail")
    }
}

Screenshot of sample code