Home > Software engineering >  Cannot convert value of type '[ASValue<T>]' to expected argument type 'Binding&
Cannot convert value of type '[ASValue<T>]' to expected argument type 'Binding&

Time:08-25

I'm building a custom component and using ForEach with a custom generic type. The issue is that this type is throwing this error:

Cannot convert value of type '[ASValue]' to expected argument type 'Binding'

public struct ArrayStepperSection<T: Hashable>: Hashable {
    public let header: String
    public var items: [ASValue<T>]
    
    public init(header: String = "", items: [ASValue<T>]) {
        self.header = header
        self.items = items
    }
}

public struct ASValue<T: Hashable>: Hashable {
    private let id = UUID()
    var item: T
    
    public init(item: T) {
        self.item = item
    }
}

public class ArrayStepperValues<T: Hashable>: Hashable, ObservableObject {
    @Published public var values: [ASValue<T>]
    @Published public var selected: ASValue<T>
    @Published public var sections: [ArrayStepperSection<T>]
    
    public init(values: [ASValue<T>], selected: ASValue<T>, sections: [ArrayStepperSection<T>]? = nil) {
        self.values = values
        self.selected = selected
        
        if sections != nil {
            self.sections = sections!
        } else {
            self.sections = [ArrayStepperSection(items: values)]
        }
    }
    
    public static func == (lhs: ArrayStepperValues<T>, rhs: ArrayStepperValues<T>) -> Bool {
        return lhs.sections == rhs.sections
    }

    public func hash(into hasher: inout Hasher) {
        hasher.combine(sections)
    }
}

struct ArrayStepperList<T: Hashable>: View {
    @Environment(\.dismiss) var dismiss
    
    @ObservedObject var values: ArrayStepperValues<T>
    
    let display: (T) -> String
    
    var body: some View {
        List {
            ForEach(values.sections, id: \.self) { section in
                Section(section.header) {
                    ForEach(section.items, id: \.self) { item in // Error happens here
                        Button(action: {
                            values.selected.item = item
                            dismiss()
                        }) {
                            HStack {
                                Text(display(item))
                                
                                Spacer()
                                
                                if values.selected.item == item {
                                    Image(systemName: "checkmark")
                                }
                            }
                        }
                    }
                }
            }
        }
        .listStyle(InsetGroupedListStyle())
        .navigationTitle(Text(display(values.selected.item)))
    }
}

CodePudding user response:

here is the test code I used to remove the error:

struct ContentView: View {
    @StateObject var values = ArrayStepperValues(values: [ASValue(item: "aaa"),ASValue(item: "bbb")], selected: ASValue(item: "aaa"))
    
    var body: some View {
        ArrayStepperList(values: values) // for testing
    }
}

struct ArrayStepperList<T: Hashable>: View {
    @Environment(\.dismiss) var dismiss
    
    @ObservedObject var values: ArrayStepperValues<T>
    
 //   let display: (T) -> String   // for testing
    
    var body: some View {
        List {
            ForEach(values.sections, id: \.self) { section in
                Section(section.header) {
                    ForEach(section.items, id: \.self) { item in
                        Button(action: {
                            DispatchQueue.main.async {
                                values.selected.item = item.item  // <-- here
                                // dismiss()  // for testing
                            }
                        }) {
                            HStack {
                             Text("\(item.item as! String)")  // for testing
                                Spacer()
                                if values.selected.item == item.item {  // <-- here
                                    Image(systemName: "checkmark")
                                }
                            }
                        }
                    }
                }
            }
        }
        .listStyle(InsetGroupedListStyle())
  //      .navigationTitle(Text(display(values.selected.item)))  // for testing
    }
}
  • Related