swiftUi:在一个屏幕上有2个选择器-应用崩溃并显示“索引超出范围" [英] swiftUi : 2 Pickers on one screen - app crash with "Index out of range"
问题描述
当我尝试用不同的观察者在屏幕上放置2个具有不同行数的桩子时. 如果我在第二行中不存在的行中选择一个, 当我转到第二个选择器应用程序时崩溃并显示以下消息: 致命错误:索引超出范围"
When I try to put 2 pikers with a different number of rows on-screen with different observers. if I select in one number of the row that not exists in the second, when I move to the second picker app crash with this message: "Fatal error: Index out of range"
public enum kTrackType {
case audio
case text
}
class kTrack: NSObject, Identifiable {
public var id = UUID()
public var trakcId: String
public var title: String
public var type: kTrackType
public init(id: String, title: String, type: kTrackType) {
self.trakcId = id
self.title = title
self.type = type
}
}
这是主要结构:
struct SelectedAudioAndSubtileView: View {
let geometry: GeometryProxy
@State var subtitlesList = [kTrack(id: "t0", title: "None", type: kTrackType.text),
kTrack(id: "t1", title: "En", type: kTrackType.text),
kTrack(id: "t2", title: "Rus", type: kTrackType.text),
kTrack(id: "t3", title: "Spn", type: kTrackType.text)]
@State var multiAudioList = [kTrack(id: "s0", title: "En", type: kTrackType.audio),
kTrack(id: "s1", title: "Rus", type: kTrackType.audio)]
@Binding var showSubtitlesPicker: Bool
@State private var selectedAudioPicker: Int = 0
@State private var selectedSubtitlePicker: Int = 0
@State private var selectedType = 0
var body: some View {
VStack {
Picker(selection: $selectedType, label: EmptyView()) {
Text("Audio").tag(0)
Text("Subtitle").tag(1)
}
.pickerStyle(SegmentedPickerStyle())
Text(self.selectedType == 0 ? "Select Audio" : "Select Subtitle")
Divider()
if selectedType == 0 {
Picker(selection: self.$selectedAudioPicker, label: Text("")) {
ForEach(self.multiAudioList, id: \.id){ name in
Text(name.title)
}
}
} else {
Picker(selection: self.$selectedSubtitlePicker, label: Text("")) {
ForEach(self.subtitlesList, id: \.id){ name in
Text(name.title)
}
}
}
Divider()
}
.background(Color(#colorLiteral(red: 0.9686274529, green: 0.78039217, blue: 0.3450980484, alpha: 1)))
.offset(y: geometry.size.height - 330)
}
重新检查后,如果您在2个选择器中有相同的行,也会发生崩溃!
After recheck, the crash happened also if you have same rows in 2 pickers!
推荐答案
在这里是这种情况:
a)selectedValue
应该与标签值匹配,因此在ForEach
中,最好使用index
而不是id
,以便可以为每个项目添加标签.
a) the selectedValue
should match the tag value, therefore in ForEach
, it's better to use index
not the id
so that you can add tag for each items.
b)ForEach
结构是一个复杂的结构,通常可以重复使用以提高性能.因此,为了强制刷新,可以将id()
修饰符添加到额外的ForEach
结构中.必须有一个没有id
的ForEach
,它提供了真正的基础数据层.
b) the ForEach
structure is a complex one and usually to be reused for performance. So in order to force it refresh, id()
modifier can be added to extra ForEach
structures. There must be one ForEach
without id
which provides the real underlying data layer.
if selectedType == 0 {
Picker (selection: self.$selectedAudioPicker, label: Text("")) {
ForEach(0..<self.multiAudioList.count){ index in
Text(self.multiAudioList[index].title).tag(index)
}
}
} else if selectedType == 1 {
Picker(selection: self.$selectedSubtitlePicker, label: Text("")) {
ForEach(0..<self.subtitlesList.count){ index in
Text(self.subtitlesList[index].title).tag(index)
}.id(0)
}
}
这篇关于swiftUi:在一个屏幕上有2个选择器-应用崩溃并显示“索引超出范围"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!