SwiftUI Picker в форме не показывает галочку

У меня есть средство выбора, встроенное в форму, однако я не могу заставить его работать, потому что он показывает галочку и выбранное значение в форме.

NavigationView {
    Form {
        Section {
                Picker(selection: $currencyCode, label: Text("Currency")) {
                    ForEach(0 ..< codes.count) {
                        Text(self.codes[$0]).tag($0)
                    }
                }
            }
    }
}

https://i.stack.imgur.com/IE5u7.gif

2 ответа

Решение

TL;DR

Ваша переменная currencyCode не соответствует типу идентификатора для каждого элемента в вашем ForEach. Либо перебирайте коды в своемForEach, или передайте свой Picker индекс.

Ниже приведены три эквивалентных примера. Обратите внимание, что@State переменная, которая передается в Picker всегда соответствует идентификатору элемента, который ForEach повторяется:

Также обратите внимание, что я выбрал значение по умолчанию для @Stateпеременная, которой нет в массиве ("", -1, UUID()), поэтому при загрузке формы ничего не отображается. Если вам нужен вариант по умолчанию, просто сделайте его значением по умолчанию для вашего@State переменная.

Пример 1: перебор кодов (например, строки)

struct ContentView: View {
    @State private var currencyCode: String = ""
    var codes: [String] = ["EUR", "GBP", "USD"]

    var body: some View {
        NavigationView {
            Form {
                Section {
                    Picker(selection: $currencyCode, label: Text("Currency")) {
                        // ID is a String ----v
                        ForEach(codes, id: \.self) { (string: String) in
                            Text(string)
                        }
                    }
                }
            }
        }
    }
}

Пример 2: итерация по индексам (например, Int)

struct ContentView: View {
    @State private var selectedIndex: Int = -1
    var codes: [String] = ["EUR", "GBP", "USD"]

    var body: some View {
        NavigationView {
            Form {
                Section {
                    Picker(selection: $selectedIndex, label: Text("Currency")) {
                        // ID is an Int --------------v
                        ForEach(codes.indices, id: \.self) { (index: Int) in
                            Text(self.codes[index])
                        }
                    }
                }
            }
        }
    }
}

Пример 3: Итерация по идентифицируемой структуре по ее типу идентификатора (например, UUID)

struct Code: Identifiable {
    var id = UUID()
    var value: String

    init(_ value: String) {
        self.value = value
    }
}

struct ContentView: View {
    @State private var selectedUUID = UUID()
    var codes = [Code("EUR"), Code("GBP"), Code("USD")]

    var body: some View {
        NavigationView {
            Form {
                Section {
                    Picker(selection: $selectedUUID, label: Text("Currency")) {
                        // ID is a UUID, because Code conforms to Identifiable
                        ForEach(self.codes) { (code: Code) in
                            Text(code.value)
                        }
                    }
                }
            }
        }
    }
}

Трудно сказать, что вы делаете не так, потому что в вашем примере нет объявления codes или currencyCode. Я подозреваю, что проблема в том, что привязка имеет другой тип, чем тег, который вы устанавливаете в сборщике (в вашем случае это Int).

Во всяком случае, это работает:

struct ContentView: View {

    let codes = Array(CurrencyCode.allCases)

    @State private var currencyCode: CurrencyCode?


    var body: some View {
        NavigationView {
            Form {
                Section {
                    Picker("Currency",
                           selection: $currencyCode) {
                            ForEach(codes, id: \.rawValue) {
                                Text($0.rawValue).tag(Optional<CurrencyCode>.some($0))
                            }
                    }
                }
            }
        }

    }
}


enum CurrencyCode: String, CaseIterable {

    case eur = "EUR"
    case gbp = "GBP"
    case usd = "USD"
}
Другие вопросы по тегам