SwiftUI App crashes with a VStack around two pickers

Viewed 134

I already found the solution, but still like to understand what the issue was to be able to transfer it to similar problems.

Take this example code:

import SwiftUI

struct ContentView: View {
    
    private var days = Array(1...31)
    @State private var selectedDay = 1
    
    private var months = [ "January", "February", "March", "April", "May", "June" ]
    @State private var selectedMonth = "January"
    
    
    var body: some View {
        NavigationView {
            Form {
                VStack {
                    Picker("Select day", selection: $selectedDay) {
                        ForEach(self.days, id: \.self) { day in
                            Text(String(day))
                        }
                    }
                    
                    Picker("Select month", selection: $selectedMonth) {
                        ForEach(self.months, id: \.self) { month in
                            Text(month)
                        }
                    }
                }
            }
        }
    }
}

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

If you then tap on any of the pickers the application will crash after a few seconds with Thread 1: EXC_BAD_ACCESS (code=2, address=0x7ffeed371fd8).

The solution was to remove the VStack.

But I still like to understand why the application crashes if there is a VStack?

What’s wrong about adding a VStack?

1 Answers

Form is actually a List and every View in Form's view builder is put into row, so combining two picker into VStack result it putting two pickers into one row and when you tap on that row which picker list should be shown? ... unknown - thus this is a reason of crash.

If you want to combine such views in form use Section, like

Form {
    Section {
        Picker("Select day", selection: $selectedDay) {
            ForEach(self.days, id: \.self) { day in
                Text(String(day))
            }
        }

        Picker("Select month", selection: $selectedMonth) {
            ForEach(self.months, id: \.self) { month in
                Text(month)
            }
        }
    }
}
Related