Picker selectedValue 更改时 SwiftUI 2.0 应用程序崩溃
SwiftUI 2.0 App crash when Picker selectedValue changed
你好,这是我的示例代码
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?]
}
它一开始是有效的,但是当 select 一个国家然后 select 另一个国家然后回到第一个选择它崩溃了,
我用的是最新的 Xcode beta 不知道是这个原因还是我的方法不对
谢谢
问题出在缓存绑定中。如果数据源发生变化,我们需要重新创建选择器。
在下面找到一个修复程序。使用 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")
}
你好,这是我的示例代码
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?]
}
它一开始是有效的,但是当 select 一个国家然后 select 另一个国家然后回到第一个选择它崩溃了, 我用的是最新的 Xcode beta 不知道是这个原因还是我的方法不对 谢谢
问题出在缓存绑定中。如果数据源发生变化,我们需要重新创建选择器。
在下面找到一个修复程序。使用 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")
}