我一直在使用SwiftUI和Xcode14的新版本,以探索使用NavigationStack进行编程导航的所有新可能性。我用一个以值作为参数的NavigationLink和.navigationDestination修饰符构建了一个小示例,在该示例中,我使用一个开关语句来确定哪个视图将被实例化:
enum Destination: String, CaseIterable, Hashable {
case view1, view2
}
struct Navigation: View {
@State private var path: [Destination] = []
var body: some View {
NavigationStack(path: $path) {
NavigationLink(value: Destination.view1, label: {
Text("Go to View1")
})
.navigationDestination(for: Destination.self, destination: { path in
switch path {
case .view1: View1()
case .view2: View2()
}
})
.navigationTitle("Root View")
}
}
}问题是,当我尝试使用功能方法重构时,试图通过召回一系列回调来替换开关:
typealias Paths = [((Destination) -> Bool, () -> any View)]
private lazy var navigation: Paths = [
({ $0 == .view1 }, { View1() }),
({ $0 == .view2 }, { View2() })
]将开关语句替换为:
navigation.first { $0.0(path) }?.1()我在这里看到了这个错误:Type 'any View' cannot conform to 'View',而且我似乎找不到解决它的方法。与any View不同,我宁愿返回some View,甚至返回View本身,但两者都不可能,因为两者都返回错误。我找到的唯一解决办法是使用AnyView,但是通过这种方式,我永久地删除了View类型,这不是很好。
谢谢您能提供的任何指导!
发布于 2022-06-12 05:04:42
Swift不允许将不同的类型放入数组(这里的类型是不同的,因为依赖于不同的View1、View2,而且视图是泛型协议,不能用作数组类型)
一种可能的方法是直接以类型移动视图生成器,因此每个案例都了解自己的视图,如
enum Destination: String, CaseIterable, Hashable {
case view1, view2
@ViewBuilder var view: some View { // << here !!
switch self {
case .view1: View1()
case .view2: View2()
}
}
}用得更简单
.navigationDestination(for: Destination.self) { $0.view }如果需要参数注入视图构造函数,则可以使用函数而不是可计算属性。
用Xcode 14 / iOS 16测试
https://stackoverflow.com/questions/72588146
复制相似问题