When using an enum with associated values as an associated value of another enum, something weird happens in SwiftUI - the outer enum inexplicably changes to a different case:
enum Value {
case whole(Number)
case fraction(Number, Number)
}
enum Number {
case int(Int)
case double(Double)
}
struct ContentView: View {
@State var value: Value = .fraction(.int(1), .int(1))
var body: some View {
VStack() {
Text("\(value)" as String)
Button("randomize denominator") {
self.value = .fraction(.int(1), .int(Int.random(in: 1...100)))
}
}
}
}
Changing the enum value where the first associated value (the numerator) is kept the same, while changing the second associated value (the denominator), toggles the case of the value between whole
and fraction
.
Here's what the screen shows (for brevity I'm omitting the CustomStringConvertable
of each enum) after each button click:
.fraction(.int(1),.int(64))
.whole(.int(1))
.fraction(.int(1),.int(23))
.whole(.int(1))
.fraction(.int(1),.int(87))
The state variable value
inexplicably toggles its case.
This erroneous behavior goes away if:
- nested enum has only one case
- nested enum doesn't have associated values
- first associated value (numerator) also changes
- the order of cases
whole
andfraction
is reversed (fraction
comes first)
This feels like a bug, but wanted to confirm, because it's not clear what SwiftUI does behind the scenes here. And if it is a bug, is there a way to address it, either by explaining why the reasons above caused it or in some other way?