我有一个 SwiftUI 视图,我希望能够显示许多其他不同视图之一:
struct View1: View {
var body: some View {
Text("View1")
}
}
struct View2: View {
var body: some View {
Text("View2")
}
}
struct View3: View {
var body: some View {
Text("View3")
}
}
struct View4: View {
var body: some View {
Text("View4")
}
}
struct ContentView: View {
@State var showView1 = false
@State var showView2 = false
@State var showView3 = false
@State var showView4 = false
@ViewBuilder var body: some View {
if (showView1) {
View1()
} else if (showView2) {
View2()
} else if (showView3) {
View3()
} else if (showView4) {
View4()
} else {
VStack {
Button ("Show View1") {
showView1 = true
}
Button ("Show View2") {
showView2 = true
}
Button ("Show View3") {
showView3 = true
}
Button ("Show View4") {
showView4 = true
}
}
}
}
}
但必须有某种方法来使用元类来避免长if else
链。
所以我尝试了类似的事情:
struct ContentView: View {
@State var showType: View.Type? = nil
@ViewBuilder var body: some View {
if let showType = showType {
showType.init()
} else {
VStack {
Button ("Show View1") {
showType = View1.type
}
Button ("Show View2") {
showType = View2.type
}
Button ("Show View3") {
showType = View3.type
}
Button ("Show View4") {
showType = View4.type
}
}
}
}
}
然而,这似乎不太正确,因为我收到此showType
声明错误:
协议“View”只能用作通用约束,因为它具有自身或关联类型要求
我相信这是因为View
它是一种协议而不是具体类型,但我不确定如何解决这个问题。在 Swift(UI) 中执行此操作的正确语法是什么?
为了显示视图,您只需使用符合的枚举即可
:View
。在主视图中,创建该枚举的一个实例,并使用按钮将其值设置为枚举中可用的任何情况。
这是一个有效的例子:
这在 SwiftUI 中并不常见。如果您只是想减少混乱,我建议使用
switch
和一个enum
值来表示每个视图。如果您甚至想删除
case
标签,您可以编写一个基于Int
索引显示特定视图的视图,但我认为这比使用枚举的编写方式更糟糕switch
。如果您确实想要存储元类型,则需要使用
AnyView
,这可能会有问题。此方法仅适用于具有无参数初始化程序的视图类型,与使用switch
甚至ViewSelector
上述方法相比,这极大地限制了它的实用性。首先将无参数初始化要求编码到协议中,
然后您可以存储一个
(any DirectlyInitializableView.Type)?
。除了接受答案中的枚举之外,您还可以使用类似以下内容:
但枚举仍然是首选。