如何在 SwiftUI 中为详细视图创建对象实例

How to create object instance for detail view in SwiftUI

我想使用带有列表的经典 iOS 工作流 —> 详细视图屏幕。而且我想不出在打开列表视图并在列表视图和详细视图之间移动时创建对象的一个​​实例的方法。通常我会使用跟随模式。


var detailVC = UIStoryboard.initiateDetailViewController()
detailVC.objectToEdit = MyObject(val1: "SomeVal", val2: "SomeAnotherVal")
detailVC.present()

所以这没关系。我正在创建 VC,手动分配应为 DetailView 存储数据的对象,为其分配新对象,然后将其推送到导航堆栈。

但在 swiftUI 中我无法这样做。

PresentationButton(destination: MyDetailViewController()) {
    Text("Add new object")
}

上面的模式将失败,因为它会创建 1 个新的 MyObject,即使它只是呈现 ListView() 本身。点击该按钮并关闭 DetailView 视图后,它将创建另外 2 个或 3 个对象实例。

其他按钮和工具,如 NavigationLink.presentation()(实际上我不知道 SwiftUI 中的任何其他导航模式)最终都是一样的。

所以我发现添加新数据对象的唯一方法是使用控制流和布尔变量修改当前视图,但我认为这两种架构的用户体验都很差。

那么你能为我推荐 SwiftUI 中这种情况的任何好的模式吗?

首先直接回答你的问题,

您可以使用 BindingBindableObject 来控制整个 SwiftUI 应用程序中的数据流。这个主题已被多次提及,因此我不再重复它,而是为您指出一些资源。

This WWDC video on data flow with SwiftUI should be the first thing you look at. It will give a great overview of what you need to know. Without a more detailed look at exactly what the code in your project is, no one but you will know which of @Binding, @ObjectBinding, @EnvironmentObject and @State to use, but this article might be able to help you figure it out. And lastly, here 是 Apple 关于状态和数据流的文档,这是学习前面提到的主题的详细信息的另一个重要资源。

另一种选择

根据您的要求,听起来您想要 UIKit UISplitViewController. You can make your own implementation of it with UIViewControllerRepresentable, or you can use one that someone has already created 的 SwiftUI 实现。

我还为前面提到的 UISplitViewController 的 SwiftUI 实现创建了一个包装器,它不太灵活,但易于使用,设置快速,并提供了不错的功能,如可选的搜索栏和能力完全处理 "Master"(您的列表)和 "Detail" 视图之间的数据流。您可以查看 here(它仍在进行中,因此使用风险自负)。如果您需要一个简单的 SplitView,无需过多自定义且易于快速设置,则此选项最适合。