我已经阅读了关于这个话题的documentation条,我相信我对它有一个基本的理解.
从理论上讲,这听起来相当不错,而且不太复杂.如果我有一个模型类ModelClass
和一个显示模型详细信息的视图ModelDetailsView
,我只需将模型实例附加到NavigationPath
,并让.navigationDestination(for: ModelClass.self)
修改器准备好接收数据和显示详细信息视图.
因此,简化后的项目设置如下所示:
前ContentView
名:
struct ContentView: View {
@StateObject private var navigator = Navigator()
var body: some View {
WindowGroup {
NavigationStack(path: $navigator.path) {
MainMenu()
.navigationDestination(for: ModelClass.self) { model in
ModelDetailsView(model: model)
}
}
.environmentObject(navigator)
}
}
}
Navigator
个班级:
class Navigator: ObservableObject {
@Published var path = NavigationPath()
func navigate(with model: any Hashable) {
path.append(model)
}
}
我们有MainMenu
米的导航:
struct MainMenu: View {
@EnvironmentObject private var navigator: Navigator
let model = ModelClass()
var body: some View {
Button("Go to details") {
navigator.navigate(with: model)
}
}
}
我对上面提到的方法有很多问题.
首先,在导航部分(navigator.navigate(with: model)
),我实际上没有在代码中指定我的意图.从这一行中,不清楚我是要导航到详细信息视图,还是要导航到将这个类实例用作属性的任何其他视图.添加 comments 有点儿 destruct 了快速代码的整洁(至少对我来说是这样).
但不管怎样,如果有必要,我会写 comments 来澄清,这应该是把我带到一个细节视图.但下一个问题要糟糕得多.
那么,如果我有多个将这个类作为属性的视图,会怎样呢?假设我有这ModelDetailsView
分,但我也有SecondaryDetailsView
分.这两种观点只有一个论点,两种观点都是ModelClass
分.现在,我应该如何写.navigationDestination
修饰语来区分这两个呢?我能做到
.navigationDestination(for: ModelClass.self) { model in
if someCondition {
ModelDetailsView(model: model)
} else {
SecondaryDetailsView(model: model)
}
}
但是,这someCondition
必须在ContentView
中,这既不实际,也不是一个好的做法.
有些地方(我找不到来源)建议导航时使用String
作为标识符.所以导航器会有一个功能
func show<V>(_ viewType: V.Type) where V: View {
path.append(String(describing: viewType.self))
}
这可以用来像这样
navigator.show(ModelDetailsView.self)
// or
navigator.show(SecondaryDetailsView.self)
这种方法的问题是不能将参数传递给视图.
.navigationDestination(for: String.self) { id in
if id == String(describing: ModelDetailsView.self) {
ModelDetailsView(model: ) // how do I get the model for the view?
}
}
所以我想知道有没有人有一个好的解决方案,可以用在更大的项目中而不会变得太难看.