The app I'm currently building works perfectly fine on iOS 13 but crashes most of the times when I click on picker view that is shown using ZStack with the error.
Fatal error: Index out of range: file Swift/ContiguousArrayBuffer.swift, line 444
The crash occurs most of the times and I am unable to find the problem.
Has anyone encountered the same issue or could anyone tell me whats causing this only in iOS 14? Thanks
While replicating the similar code in a demo app, it seems to run fine most of the times and crashes rarely. Below is the code for the demo app.
struct ContentView: View {
@State var showPicker = false
@State var selectedIndex = 0
@State var pickerValues: [String] = []
@State var selectedValue = ""
var body: some View {
ZStack() {
VStack() {
if !pickerValues.isEmpty {
Text(selectedValue)
.padding()
}
Button {
self.pickerValues = [
"First Element",
"Second Element",
"Third Element",
"Fourth Element",
"Fifth Element",
"Sixth Element",
"Seventh Element"
]
self.showPicker.toggle()
} label: {
Text("Show Picker")
}
}
if showPicker {
AppPickerView(title: "Picker", data: self.pickerValues, selectedData: self.$selectedValue, show: self.$showPicker)
}
}
}
}
struct AppPickerView: View {
var title: String
var data: [String]
@Binding var selectedData: String
@Binding var show: Bool
@State var showAnimation: Bool = false
var body: some View {
ZStack {
Color.init(#colorLiteral(red: 0, green: 0, blue: 0, alpha: 0.3980798856))
VStack() {
Text(title).font(.system(size: 20))
.fontWeight(.semibold)
.padding()
picker.animation(nil)
cancelAndSelect.animation(nil)
}
.background(Color.white)
.cornerRadius(12)
.padding()
.transition(.opacity)
.offset(x: 0, y: showAnimation ? 0 : 50)
.opacity(showAnimation ? 1 : 0)
.animation(Animation.easeOut(duration: 0.25))
.edgesIgnoringSafeArea(.all)
}.onAppear() {
self.showAnimation = true
}
}
var picker: some View {
Picker(selection: $selectedData, label: Text(""),
content: {
ForEach(data, id: \.self) { (string: String) in
Text(string)
}
}).pickerStyle(WheelPickerStyle())
.labelsHidden()
.frame(height: 150)
}
var datePicker: some View {
Picker(selection: $selectedData, label: Text(""),
content: {
ForEach(data, id: \.self) { (string: String) in
Text(string)
}
}).pickerStyle(WheelPickerStyle())
.labelsHidden()
.frame(height: 150)
}
var cancelAndSelect: some View {
HStack() {
Button(action: {
self.hideAppPicker()
}) {
Text("Cancel")
}.buttonStyle(BackButtonStyle())
Button(action: {
self.hideAppPicker()
print(self.selectedData)
}) {
Text("Ok")
}.buttonStyle(ForwardButtonStyle())
}
.frame(height: 50)
.padding(.all, 10)
}
func hideAppPicker() {
self.showAnimation = false
self.show.toggle()
}
func selectInitalData() {
if let firstElement = self.data.first, self.selectedData.isEmpty {
self.selectedData = firstElement
}
}
}
struct BackButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.foregroundColor(.primary)
.frame(maxWidth: .infinity)
.frame(height: 40)
.background(Color.secondary)
.cornerRadius(20)
.shadow(color: Color.secondary.opacity(0.4), radius: 5, x: 2, y: 2)
}
}
struct ForwardButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.frame(maxWidth: .infinity)
.frame(height: 40)
.foregroundColor(.white)
.background(Color.primary)
.scaleEffect(configuration.isPressed ? 0.95 : 1)
.opacity(configuration.isPressed ? 0.5 : 1)
.cornerRadius(20)
.shadow(color: Color.primary.opacity(0.4), radius: 5, x: 2, y: 2)
}
}
struct SecondaryButtonStyle: ButtonStyle {
func makeBody(configuration: Self.Configuration) -> some View {
configuration.label
.frame(maxWidth: .infinity)
.frame(height: 40)
.background(Color.white)
.cornerRadius(20)
.scaleEffect(configuration.isPressed ? 0.95 : 1)
.opacity(configuration.isPressed ? 0.5 : 1)
.overlay(Capsule().stroke(Color.primary, lineWidth: 1))
.shadow(color: Color.secondary.opacity(0.4), radius: 5, x: 2, y: 2)
}
}