Tenho uma visualização SwiftUI que gostaria de poder mostrar uma das muitas outras visualizações diferentes :
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
}
}
}
}
}
Mas tem que haver alguma maneira de usar uma metaclasse para evitar a if else
cadeia longa.
Então tentei algo como:
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
}
}
}
}
}
Entretanto, isso não parece muito correto, pois recebo este erro para a showType
declaração:
O protocolo 'View' só pode ser usado como uma restrição genérica porque possui requisitos de tipo próprio ou associado
Acredito que isso seja porque View
é um protocolo e não um tipo concreto, mas não tenho certeza de como contornar isso. Qual seria a sintaxe correta para fazer isso em Swift(UI)?
Para mostrar as visualizações no local, você pode simplesmente usar uma enumeração que esteja em conformidade com
:View
.Na sua visualização principal, você cria uma instância dessa enumeração e define seu valor usando os botões para qualquer um dos casos disponíveis na enumeração.
Aqui está um exemplo prático:
Isso não é algo idiomático para se fazer no SwiftUI. Se você só quer reduzir a desordem, eu sugeriria usar a
switch
e umenum
valor para representar cada visualização.Se você quiser remover até mesmo os
case
rótulos, você pode escrever uma visualização que mostre uma visualização específica com base em umInt
índice, mas eu consideraria essa uma maneira pior de escrever isso do queswitch
com enumerações.Se você realmente quiser armazenar um metatipo, você precisaria usar
AnyView
, o que pode ser problemático . Essa abordagem só funcionaria com tipos de visualização que têm um inicializador sem parâmetros, o que limita muito sua utilidade em comparação ao uso de umswitch
, ou mesmo oViewSelector
acima.Primeiro você codificaria o requisito do inicializador sem parâmetros em um protocolo,
Você pode então armazenar um
(any DirectlyInitializableView.Type)?
.Além de enum da resposta aceita, você pode usar algo assim:
Mas ainda assim, enum é o preferido.