xcode - swiftUi:一个屏幕上的 2 个选择器 - 应用程序崩溃并显示“索引超出范围”
问题描述
当我尝试用不同的观察者在屏幕上放置 2 个具有不同行数的 piker 时。如果我在第二个不存在的行中选择一个数字,当我移动到第二个选择器应用程序崩溃并显示以下消息:“致命错误:索引超出范围”
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 个选择器中有相同的行,也会发生崩溃!
解决方案
这是情况:
a)selectedValue
应该与标签值匹配,因此在 中ForEach
,最好不要使用index
,id
这样您就可以为每个项目添加标签。
b) 该ForEach
结构是一个复杂的结构,通常为了性能而重复使用。因此,为了强制刷新,id()
可以将修饰符添加到额外的ForEach
结构中。必须有一个ForEach
没有id
它提供真正的底层数据层。
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)
}
}
推荐阅读
- netlogo - NetLogo中的内存转储,有可能吗?
- sql-server - 筛选表并将其从 SQL Server 移动到 MS Access
- python - 从 s3 加载 FastText 模型而不在本地保存
- apache-kafka - 使用 kafka-json-schema-console-consumer 使用 JSON 消息时打印密钥
- c# - Microsoft Graph 发送相同的消息
- javascript - 与 iPhone 上的 iframe 内容交互的问题
- mysql - 用于存储最后交易日期的 SQL
- angular - Angular Bootstrap 拨动开关
- javascript - 我需要转换一小段代码,在短语中添加空格并且不知道该怎么做
- mongodb - Mongod 没有运行,但服务和 shell 运行