I'm trying to show different views (with the same base) depending on an enum value but depending on how to "inspect" the enum the behavior changes. This is the code (I'm using a "useSwitch" variable to be able to alternate between both behaviors)
import SwiftUI
enum ViewType: CaseIterable {
case type1
case type2
var text: String {
switch self {
case .type1:
return "Type 1"
case .type2:
return "Type 2"
}
}
}
final class BaseVM: ObservableObject {
let type: ViewType
@Published var requestingData = false
init(type: ViewType) {
self.type = type
}
@MainActor func getData() async {
requestingData = true
try! await Task.sleep(nanoseconds: 1_000_000_000)
requestingData = false
}
}
struct BaseView: View {
@StateObject var vm: BaseVM
var body: some View {
Group {
if vm.requestingData {
ProgressView("Getting data for \(vm.type.text)")
} else {
Text("\(vm.type.text)")
}
}
.onAppear {
Task {
await vm.getData()
}
}
}
}
struct TestZStackView: View {
private let types = ViewType.allCases
@State var currentType: ViewType = .type1
private var useSwitch = true
var body: some View {
VStack {
if useSwitch {
Group {
switch currentType {
case .type1:
BaseView(vm: BaseVM(type: currentType))
case .type2:
BaseView(vm: BaseVM(type: currentType))
}
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
} else {
BaseView(vm: BaseVM(type: currentType))
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
Spacer()
Picker("", selection: $currentType) {
ForEach(types, id: \.self) {
Text($0.text)
}
}
.pickerStyle(.segmented)
.padding(.top, 20)
}
.padding()
}
}
struct TestZStackView_Previews: PreviewProvider {
static var previews: some View {
TestZStackView()
}
}
I don't understand why using a switch (useSwitch == true) refreshes the view but using the constructor passing the enum as parameter (useSwitch = false) doesn't refresh the view... It can't detect that the currentType has changed if used as parameter instead of checking it using a switch?