【问题标题】:Forcing the destination of a NavigationLink in a navigation bar item to the secondary/detail view将导航栏项目中 NavigationLink 的目标强制到辅助/详细视图
【发布时间】:2019-08-31 01:02:53
【问题描述】:

我试图在 SwiftUI 中重现 UISplitViewController 的行为,特别是在 iPad 上。此 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 很好地解释了这种情况。)

【问题讨论】:

    标签: swiftui


    【解决方案1】:

    请注意,在大尺寸 iPhone 上,横向 (https://stackoverflow.com/a/57345540/7786555) 会出现同样的问题

    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

    【讨论】:

    • 这行得通,但感觉很hacky。我同意这可能是一个错误。我提出了一个问题(FB7201467);会看到苹果对此有什么看法。
    【解决方案2】:

    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")
        }
    }
    

    【讨论】:

    • 我明确不想将“添加新事物”控件放在列表中。多年来,iOS 的惯例是在导航栏中有一个 + 按钮来添加新事物。如果现在 SwiftUI 无法做到这一点也没关系,但我希望他们能解决这个缺点。
    • 啊,还不清楚。在这种情况下,点击添加导航栏按钮应该会显示一个模式视图控制器而不显示详细信息,或者如果该项目只是一个文本字段,您可以使用警报,例如如果它是文件夹标题,最后您可以将新项目添加到列表中,然后以编程方式选择它,然后如果他们从未完成的项目返回或取消,您可以再次删除它(与 Notes 中的新注释相同)返回时为空)。
    猜你喜欢
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-11
    • 1970-01-01
    相关资源
    最近更新 更多