我正在构建一个包含不同示例的演示应用程序,并且我希望根视图List能够导航到不同的示例视图。因此,我尝试创建一个Example可以采用不同目的地View的通用结构,如下所示:
struct Example<Destination: View> {
let id: UUID
let title: String
let destination: Destination
init(title: String, destination: Destination) {
self.id = UUID()
self.title = title
self.destination = destination
}
}
struct Example1View: View {
var body: some View {
Text("Example 1!")
}
}
struct Example2View: View {
var body: some View {
Text("Example 2!")
}
}
struct ContentView: View {
let examples = [
Example(title: "Example 1", destination: Example1View()),
Example(title: "Example 2", destination: Example2View())
]
var body: some View {
List(examples, id: \.id) { example in
NavigationLink(destination: example.destination) {
Text(example.title)
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,这会导致错误,因为它examples是一个异构集合:
我完全理解为什么这是坏的;我正在创建一个异构的示例数组,因为每个Example结构都有自己不同的强类型目标。但我不知道如何实现我想要的,这是一个我可以制作的数组,List其中有许多不同的允许目的地。
我过去遇到过这种事情,过去我通过包装我的泛型类型并只公开我需要的确切属性来解决它(例如,如果我有一个有标题的泛型类型,我将制作一个仅公开标题的包装结构和协议,然后制作该包装结构的数组)。但在这种情况下,NavigationLink需要拥有泛型类型本身,因此我无法以非泛型方式向其公开属性。
您可以使用类型擦除的 wrapper AnyView。相反,使得Example通用的,使得它的目的地视图内是类型AnyView,敷在你的看法AnyView构建时Example。
例如:
struct Example {
let id: UUID
let title: String
let destination: AnyView
init(title: String, destination: AnyView) {
self.id = UUID()
self.title = title
self.destination = destination
}
}
struct Example1View: View {
var body: some View {
Text("Example 1!")
}
}
struct Example2View: View {
var body: some View {
Text("Example 2!")
}
}
struct ContentView: View {
let examples = [
Example(title: "Example 1", destination: AnyView(Example1View())),
Example(title: "Example 2", destination: AnyView(Example2View()))
]
var body: some View {
NavigationView {
List(examples, id: \.id) { example in
NavigationLink(destination: example.destination) {
Text(example.title)
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
658 次 |
| 最近记录: |