Home > Back-end >  SwiftUI picker in Form not working properly
SwiftUI picker in Form not working properly

Time:09-25

I'm struggling with this weird Picker behavior. Basically, when I tap on the picker row I can see the options, but every time I tap on a row, nothing happens. No checkmark, no coming back to previous view and no selection. I tried also adding id: \.self in the ForEach, but nothing changes. I'm using iOS 15 with Xcode 13, but the problem is present also on iOS 14 and Xcode 12.x. Here's the code of my view:


@State private var month: Month?
@State private var category: Category?

var body: some View {
    NavigationView {
        VStack {
            Form {
                Section {
                    Picker(month?.name ?? "Seleziona il mese", selection: $month) {
                        ForEach(model.months) { month in
                            Text(month.name).tag(month)
                        }
                    }
                    Picker(category?.name ?? "Seleziona la categoria", selection: $category) {
                        ForEach(model.categories) { category in
                            Text(category.name).tag(category)
                        }
                    }
                }
            }
            Spacer()
        }
        .navigationTitle("Aggiungi Spesa")
    }
}

Here's the code of Month (Category is basically the same):

class Month: Decodable, AirtableRecord, Identifiable {
    
    var id: String
    var createdTime: String
    var number: Int
    var name: String
    var completeName: String
    
    init(
        id: String,
        createdTime: String,
        number: Int,
        name: String,
        completeName: String) {
        
        self.id = id
        self.createdTime = createdTime
        self.number = number
        self.name = name
        self.completeName = completeName
    }
    
    required init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        id = try container.decode(String.self, forKey: .id)
        createdTime = try container.decode(String.self, forKey: .createdTime)
        let fields = try container.nestedContainer(keyedBy: FieldsKeys.self, forKey: .fields)
        name = try fields.decode(String.self, forKey: .name)
        number = try fields.decode(Int.self, forKey: .number)
        completeName = try fields.decode(String.self, forKey: .completeName)
    }
    
    enum CodingKeys: String, CodingKey {
        case id
        case createdTime
        case fields
    }
    
    enum FieldsKeys: String, CodingKey {
        case number         = "Numero"
        case name           = "Nome"
        case completeName   = "Key"
    }
}

extension Month: Equatable {
    
    static func == (lhs: Month, rhs: Month) -> Bool {
        return lhs.id == rhs.id
    }
}

extension Month: Hashable {
    
    func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
}

extension Month: CustomStringConvertible {
    var description: String {
        return "\(completeName)"
    }
}

CodePudding user response:

This happens with optionals quite a bit you just have to specify type

Change your tags to something like this

.tag(month as? Month)

.tag(category as? Category)

The types have to match exactly. month and category are non-optionals so they need to be cast to optionals since your @State is an optional

  • Related