swiftUi:一个屏幕上有2个选择器-应用程序崩溃,出现“索引超出范围”

时间:2019-11-26 14:40:46

标签: xcode swiftui picker

当我尝试用不同的观察者在屏幕上放置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个选择器中有相同的行,也会发生崩溃!

1 个答案:

答案 0 :(得分:1)

这里是情况:

a)selectedValue应该与标签值匹配,因此在ForEach中,最好使用index而不是id,以便可以为每个项目添加标签。

b)ForEach结构是一个复杂的结构,通常可以重复使用以提高性能。因此,为了强制刷新,可以将id()修饰符添加到额外的ForEach结构中。必须有一个没有ForEach的{​​{1}},它提供了真正的基础数据层。

id