3

I got some (unexplained) crashes earlier today, and simplified my code to what is seen below. The crashing went away, but I am not 100% sure. Is the code below the correct way to create Binding on an array of enums? And if yes, can this code be made simpler?

import SwiftUI

enum TheEnum: Hashable {
    case one(Int), two(Float)
}

class TestModel : ObservableObject {
    @Published var enumArray = [TheEnum.one(5), TheEnum.two(6.0)]
}

struct ContentView: View {
    @ObservedObject var testModel = TestModel()
    var body: some View {
        HStack {
            ForEach(testModel.enumArray, id: \.self) { value -> AnyView in
                switch value {
                case .one(var intVal):
                    let b = Binding(get: { 
                        intVal
                    }) {
                        intVal = $0
                    }
                    return AnyView(IntView(intVal: b))
                case .two(var floatVal):
                    let b = Binding(get: {
                        floatVal
                    }) {
                        floatVal = $0
                    }
                    return AnyView(FloatView(floatVal: b))
                }
            }
        }
    }
}

struct IntView: View {
    @Binding var intVal: Int
    var body: some View {
        Text("\(intVal)")
    }
}

struct FloatView: View {
    @Binding var floatVal: Float
    var body: some View {
        Text("\(floatVal)")
    }
}
swift nub
  • 2,747
  • 3
  • 17
  • 39
  • I don't understand why you want to pass a binding into IntView and FloatView when you just display them. – Michael Salmon Sep 13 '19 at 06:57
  • The only reason to bind to an associated value is to update it. See https://stackoverflow.com/questions/52535970/changing-associated-value-of-enum-swift I don't think that you code would even do that, I am pretty sure that you would update the temporary local variable. – Michael Salmon Sep 13 '19 at 08:47
  • The code provided here is only an example. In my real code, I am modifying the values instead of just displaying them. – swift nub Sep 13 '19 at 10:50
  • Strange that you had some unexplained crashes then. – Michael Salmon Sep 13 '19 at 14:54
  • Before i had it more complex. But it was essentially the same code. Probably i was doing something wrong before. But if what i have up there is the correct way to do bindings on an array, then i'll stay with this. – swift nub Sep 13 '19 at 14:57
  • 1
    You aren't binding an array, you are trying to bind to the associated value of an enum. Personally I would pass the array and an index but you may be able to bind to the element in the array.and use a mutating function as in https://stackoverflow.com/questions/31488603/can-i-change-the-associated-values-of-a-enum/31488680#31488680 I am pretty sure that changing an element of an array will not send an objectWillChange message as the array itself is not changed. – Michael Salmon Sep 13 '19 at 15:14
  • I'm facing a crash too when I try to pass a binding like this: `@State private var myVar: SomeEnum = .someValue` and in the receiving view that binding becomes like this: `@Binding var myVar: SomeEnum` in the View's variables list, I know that some of you would say why do you pass @State variable to another view, I'd say that the receiving view is actually a subview of the main view which has this enum, until now i couldn't solve this crash and I don't know why it happens. – JAHelia Jun 28 '20 at 07:40

0 Answers0