当我尝试用不同的观察者在屏幕上放置2个带有不同行数的桩子时。 如果我在第二行中不存在的行中选择一个, 当我转到第二个选择器应用程序时崩溃并显示以下消息: “致命错误:索引超出范围”
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个选择器中有相同的行,也会发生崩溃!
答案 0 :(得分:1)
这里是情况:
a)selectedValue应该与标签值匹配,因此在ForEach中,最好使用index
而不是id
,以便可以为每个项目添加标签。
b)ForEach结构是一个复杂的结构,通常可以重复使用以提高性能。因此,为了强制刷新,可以将id()
修饰符添加到额外的ForEach结构中。必须有一个没有ForEach
的{{1}},它提供了真正的基础数据层。
id