我在将 UIKit 架构模式转换为 SwiftUI 时遇到问题。我目前的模式主要是带有协调器/路由器的 MVVM。添加@ObservableObject/@Published 后,MVVM 部分看起来非常简单自然。但是协调/路由似乎不直观。View 和协调(导航)功能在 SwiftUI 中紧密耦合。似乎真的不可能将它们与使用辅助 struct 分开AnyView
。
这里有一个例子:我想在 SwiftUI 中创建一个可重用的行/单元格。假设生产中的这一行非常复杂,因此我想重用它。我也想把它放在另一个模块中,这样我就可以在多个目标中重用它。(如 iOS、macCatalyst 等...)
现在我想控制当用户点击该视图或该视图中的按钮时会发生什么。根据上下文,我需要导航到不同的目的地。据我所知,可能的 NavigationLink 目标必须要么硬连线到视图中,要么AnyView
必须传递到视图中。
这里有一些示例代码。此单元格/行包含两个按钮。我想导航到依赖于上下文而不是硬连线到代码中的其他视图:
struct ProductFamilyRow: View {
@State private var selection: Int? = 0
let item: ProductFamilyItem
let destinationView1: AnyView
let destinationView2: AnyView
var body: some View {
VStack {
NavigationLink(
destination: destinationView1,
tag: 1,
selection: self.$selection
) {
EmptyView()
}
NavigationLink(
destination: destinationView2,
tag: 2,
selection: self.$selection
) {
EmptyView()
}
HStack {
Text(item.title)
Button("Destination 1") {
self.selection = 1
}.foregroundColor(Color.blue)
Button("Destination 2") {
self.selection = 2
}.foregroundColor(Color.blue)
}
//Image(item.image)
}.buttonStyle(PlainButtonStyle())
}
}
这似乎是 SwiftUI 的一个主要设计缺陷。AnyView
除了使用hack之外,具有导航链接的可重用组件基本上是不可能的。据我所知AnyView
,仅用于需要类型擦除并且具有相当一些性能缺陷的特定用例。所以我不认为这是使用 SwiftUI 创建可重用、可导航视图的惯用解决方案。
这真的是唯一的解决方案吗?也许我完全错了,这无论如何都是错误的方向。我在某处读到(再也找不到帖子了..)关于使用一些中央状态来指示要显示哪个视图,但我没有看到如何执行此操作的具体示例。
第二个挑战:我也不希望单元格对任何其他点击做出反应,然后对按钮做出反应。但是,如果点击,似乎无法控制单元格导航到的位置。(所以不要点击其中一个按钮,而是点击单元格中的任何位置)在当前示例代码中,它(出于任何原因)导航到“Destination 2”。
提前致谢。