辅助选取器的“ ForEach”给我致命错误:索引超出范围

时间:2020-10-03 17:56:27

标签: foreach swiftui picker

每次启动 secondary 选择器时,都会出现此错误。
第一个选择器工作正常。
但是,当我切换选择器并滚动时,我得到以下信息:
enter image description here

这是我的完整代码(作为对此问题的测试):

import SwiftUI

struct ContentView: View {
    @State private var selectedItem = 0
    @State private var isMainPickerHidden = false
    @State private var isSecondaryPickerHidden = true

    var colors = ["Red", "Green", "Blue", "Tartan"]
    var sizes = ["Tiny", "Small", "Medium", "Large", "Super Size"]

    var body: some View {
        ZStack {
            Color.yellow.edgesIgnoringSafeArea(.all)
            ZStack {
                VStack {
                    Picker(selection: $selectedItem, label: Text("Please choose a color")) {
                        ForEach(colors.indices, id: \.self) {
                            Text(self.colors[$0])
                        }
                    }.hiddenConditionally(isHidden: isMainPickerHidden)

                    Text("You selected: \(colors[selectedItem])")
                        .hiddenConditionally(isHidden: isMainPickerHidden)
                }

                VStack {
                    Picker(selection: $selectedItem, label: Text("Please choose a size")) {
                        ForEach(sizes.indices, id: \.self) {
                            Text(self.sizes[$0])
                        }
                    }.hiddenConditionally(isHidden: isSecondaryPickerHidden)

                    Text("You selected: \(sizes[selectedItem])")
                        .hiddenConditionally(isHidden: isSecondaryPickerHidden)
                    Spacer()
                    Button(action: {
                        isSecondaryPickerHidden = !isSecondaryPickerHidden
                        isMainPickerHidden = !isMainPickerHidden
                    }) {
                        Text("Switch Pickers")
                    }.padding()
                }
            }
        }
    }
}

// =========================================================================================================

extension View {
    func hiddenConditionally(isHidden: Bool) -> some View {
        isHidden ? AnyView(hidden()) : AnyView(self)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

enter image description here

ForEach {}避免此问题的正确语法是什么?

1 个答案:

答案 0 :(得分:1)

这是因为两个选择器都使用相同的selectedItem

如果在第二个选择器中选择最后一个项目(索引4),然后切换到第一个选择器(最大索引= 3),则在此行:

Text("You selected: \(colors[selectedItem])")

您将尝试访问超出范围的索引。


要解决此问题,您可以为每个选择器使用单独的@State变量:

struct ContentView: View {
    @State private var selectedColorIndex = 0
    @State private var selectedSizeIndex = 0
Picker(selection: $selectedColorIndex, label: Text("Please choose a color")) {
Picker(selection: $selectedSizeIndex, label: Text("Please choose a size")) {