Secondary Picker's 'ForEach' gives me Fatal Error: Index Out of Range
Secondary Picker's 'ForEach' gives me Fatal Error: Index Out of Range
每次启动 secondary 选择器时都会出现此错误。
第一个选择器工作正常。
但是,当 我切换选择器 并滚动时,我得到以下信息:
这是我的全部代码(作为对此问题的测试而编写):
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[[=10=]])
}
}.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[[=10=]])
}
}.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()
}
}
ForEach{} 避免此问题的正确语法是什么?
这是因为您对两个选择器使用相同的selectedItem
。
如果在第二个选择器中你 select 最后一个项目(索引 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")) {
每次启动 secondary 选择器时都会出现此错误。
第一个选择器工作正常。
但是,当 我切换选择器 并滚动时,我得到以下信息:
这是我的全部代码(作为对此问题的测试而编写):
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[[=10=]])
}
}.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[[=10=]])
}
}.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()
}
}
ForEach{} 避免此问题的正确语法是什么?
这是因为您对两个选择器使用相同的selectedItem
。
如果在第二个选择器中你 select 最后一个项目(索引 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")) {