Reputation: 2219
I’m trying to build what I thought was a simple form in SwiftUI, but am getting the error “The compiler is unable to type check this expression; try breaking up the expression into distinct sub sections” on the view being returned from the body (in this case Form, but I’ve also tried VStack). If I start removing some of the subviews, it seems to resolve, even though none of my views directly returns 10 subviews, which I believe is the limit for a single view (except for views returned in ForEach).
import SwiftUI
struct CreateDispatchView: View {
@State private var customerId: Int = 0
@State private var name: String = ""
@State private var phone: String = ""
@State private var description: String = ""
@State private var priorityId: Int = 0
@State private var callTypeId: Int = 0
@State private var bay: String = ""
@State private var poTicket: String = ""
@State private var outOfChemicals: Bool = false
@State private var isReturnCall: Bool = false
var body: some View {
Form { // <-- Error is shown here
Section {
Picker("Customer", selection: $customerId) {
ForEach(0 ..< 10) {
Text("Customer \($0)")
}
}
TextField("Name", text: $name)
TextField("Phone", text: $phone)
TextField("Description", text: $description)
TextField("Bay", text: $bay)
TextField("PO ticket", text: $poTicket)
}
Section {
Picker("Priority", selection: $priorityId) {
ForEach(0 ..< 2) {
Text("Priority \($0)")
}
}
Picker("Call type", selection: $callTypeId) {
ForEach(0 ..< 3) {
Text("Call type \($0)")
}
}
}
Section {
Toggle(isOn: $outOfChemicals) {
Text("Out of chemicals")
}
Toggle(isOn: $isReturnCall) {
Text("Is return call")
}
}
}
}
}
struct CreateDispatchView_Previews: PreviewProvider {
static var previews: some View {
CreateDispatchView()
}
}
Upvotes: 3
Views: 2311
Reputation: 10355
The handling of large nested ViewBuilder
expressions is a weak point in the current swift compiler. Generally speaking, though, its advice to "try breaking up the expression into distinct sub sections" is a good one: refactoring these monolithic ViewBuilder
expressions out into separate dynamic variables is a good way to improve performance (plus it helps in isolating actual errors).
Here's an example of how you might refactor your code to compile successfully:
struct CreateDispatchView: View {
@State private var customerId: Int = 0
@State private var name: String = ""
@State private var phone: String = ""
@State private var description: String = ""
@State private var priorityId: Int = 0
@State private var callTypeId: Int = 0
@State private var bay: String = ""
@State private var poTicket: String = ""
@State private var outOfChemicals: Bool = false
@State private var isReturnCall: Bool = false
var body: some View {
Form {
customerSection
prioritySection
infoSection
}
}
private var customerSection: some View {
Section {
Picker("Customer", selection: $customerId) {
ForEach(0 ..< 10) {
Text("Customer \($0)")
}
}
TextField("Name", text: $name)
TextField("Phone", text: $phone)
TextField("Description", text: $description)
TextField("Bay", text: $bay)
TextField("PO ticket", text: $poTicket)
}
}
private var prioritySection: some View {
Section {
Picker("Priority", selection: $priorityId) {
ForEach(0 ..< 2) {
Text("Priority \($0)")
}
}
Picker("Call type", selection: $callTypeId) {
ForEach(0 ..< 3) {
Text("Call type \($0)")
}
}
}
}
private var infoSection: some View {
Section {
Toggle(isOn: $outOfChemicals) {
Text("Out of chemicals")
}
Toggle(isOn: $isReturnCall) {
Text("Is return call")
}
}
}
}
Upvotes: 4