Сбой приложения SwiftUI 2.0 при изменении значения Picker selected

привет вот мой пример кода

      import SwiftUI

final class ViewModel: ObservableObject {
    @Published var countries: [Country?] = [
        Country(id: 0, name: "country1", cities: ["c1 city1", "c1 city2", "c1 city3"]),
        Country(id: 1, name: "country2", cities: ["c2 city1", "c2 city2", "c2 city3"]),
        Country(id: 2, name: "country3", cities: ["c3 city1", "c3 city2", "c3 city3"])
    ]
}

struct ContentView: View {
    
    @ObservedObject var viewModel = ViewModel()
    @State private var selectedCountry: Country? = nil
    @State private var selectedCity: String? = nil
    
    var body: some View {
        VStack {
            Picker("", selection: $selectedCountry) {
                ForEach(viewModel.countries, id: \.self) { country in
                    Text(country!.name).tag(country)
                }
            }
            .pickerStyle(SegmentedPickerStyle())
            Text(selectedCountry?.name ?? "no selection")
            
            if selectedCountry != nil {
                Picker("", selection: $selectedCity) {
                    ForEach(selectedCountry!.cities, id: \.self) { city in
                        Text(city!).tag(city)
                    }
                }
                .pickerStyle(SegmentedPickerStyle())
                Text(selectedCity ?? "no selection")
            }
        }
        .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct Country: Codable, Hashable, Identifiable {
    var id: Int
    var name: String
    var cities: [String?]
}

сначала он работает, но когда выберите страну, затем выберите другую страну, затем вернитесь к первому выбору, он выйдет из строя, я использую последнюю бета-версию Xcode, я не знаю, причина ли это, или мой подход неправильный, спасибо

1 ответ

Решение

Проблема в кешированной привязке. Нам нужно воссоздать сборщик, если источник данных изменился.

Найдите исправление ниже. Протестировано с Xcode 12.4 / iOS 14.4

      if selectedCountry != nil {
    Picker("", selection: $selectedCity) {
        ForEach(selectedCountry!.cities, id: \.self) { city in
            Text(city!).tag(city)
        }
    }
    .pickerStyle(SegmentedPickerStyle())
    .id(selectedCountry!)                // << here !!

    Text(selectedCity ?? "no selection")
}
Другие вопросы по тегам