Function Issue: Closure containing a declaration cannot be used with result builder 'ViewBuilder'

I am having trouble with running my save button function. I am not sure why the function won't work.
I thought it was because i have too many arguments. I am just not sure what to do.


struct addALandmarkForm: View {
  @Environment(\.presentationMode) var presentatoinMode
  @EnvironmentObject var listViewModel: ListViewModel
  @State var newLocationName: String = ""
  @State var texts: String = "Enter a Description"
  @State public var newPropertyType1 = false
  @State public var propertyPrice: String = ""
  @State var email: String = ""
  @State var ownerName: String = ""
   
  @State var alerTitle: String = ""
  @State var showAlert: Bool = false
   
  var body: some View {
     
    NavigationView {
      Form {
        TextField("Location Name", text: $newLocationName)
        Toggle("Property is Private ",
            isOn: $newPropertyType1)
        if newPropertyType1{
          TextField("Asking/Starting Price", text: $propertyPrice)
            .keyboardType(.numberPad)
        }
        TextEditor(text: $texts )
         
        Section(header: Text("Owner")){
          TextField("Enter an Email", text: $email)
          TextField("Owner's First Name", text: $ownerName)
        }
        Section(header: Text("Submit")){
           
          Button (action: saveButtonPressed, label:{
            Label("Submit New Location", systemImage: "plus.square")
          })
        }
      }
      .navigationBarTitle("Add a New Location")
       
    }

// this is where my issue is. Thi is the error that i get.
//Closure containing a declaration cannot be used with result builder 'ViewBuilder'
    func saveButtonPressed() {
        listViewModel.addItem(title: newLocationName, descrip: texts, price: propertyPrice, mail: email, owner: ownerName)
        presentatoinMode.wrappedValue.dismiss()
      }
    }
  }


struct addALandmarkForm_Previews: PreviewProvider {
  static var previews: some View {
    NavigationView{
      addALandmarkForm()
    }
    .environmentObject(ListViewModel())
  }
}

import SwiftUI


class ListViewModel: ObservableObject {
   
  @Published var items: [ItemModel] = []
   
  init(){
    getItems()
  }
  func getItems() {
    let newItems = [
      ItemModel(newLocationName: "PFT", text: "Engineering building for LSU students. A great place to study and do business", newPropertyType1: true, propertyPrice: "1200", email: "test@email", ownerName: "Rob"),
      ItemModel(newLocationName: "PFT", text: "Engineering building for LSU students. A great place to study and do business", newPropertyType1: true, propertyPrice: "1200", email: "test@email", ownerName: "Bob"),
      ItemModel(newLocationName: "PFT", text: "Engineering building for LSU students. A great place to study and do business", newPropertyType1: true, propertyPrice: "1200", email: "test@email", ownerName: "Taylor")
    ]
    items.append(contentsOf: newItems)
  }
  func addItem(title: String, descrip: String, price: String, mail: String, owner: String){
    let newItem = ItemModel(newLocationName: title, text: descrip, newPropertyType1: false, propertyPrice: "1200", email: mail, ownerName: owner)
      items.append(newItem)
  }
}
Answered by OOPer in 697252022

The declaration of function saveButtonPressed() resides in the body of body.

You need to move it out of body.

struct AddALandmarkForm: View {
    @Environment(\.presentationMode) var presentatoinMode
    @EnvironmentObject var listViewModel: ListViewModel
    @State var newLocationName: String = ""
    @State var texts: String = "Enter a Description"
    @State public var newPropertyType1 = false
    @State public var propertyPrice: String = ""
    @State var email: String = ""
    @State var ownerName: String = ""
    
    @State var alerTitle: String = ""
    @State var showAlert: Bool = false
    
    var body: some View {
        
        NavigationView {
            Form {
                //...
            } //<- End of `Form`
            .navigationBarTitle("Add a New Location")
            
        } //<- End of `NavigationView`
    } //<- End of `body`
    
    func saveButtonPressed() {
        listViewModel.addItem(title: newLocationName, descrip: texts, price: propertyPrice, mail: email, owner: ownerName)
        presentatoinMode.wrappedValue.dismiss()
    }
}

By the way, in Swift, type names should start with Capital letters. You should not use addALandmarkForm as a struct name in Swift.

The swift compiler's error message is misleading, but what happens if you write presentationMode instead of presentatoinMode ?

Accepted Answer

The declaration of function saveButtonPressed() resides in the body of body.

You need to move it out of body.

struct AddALandmarkForm: View {
    @Environment(\.presentationMode) var presentatoinMode
    @EnvironmentObject var listViewModel: ListViewModel
    @State var newLocationName: String = ""
    @State var texts: String = "Enter a Description"
    @State public var newPropertyType1 = false
    @State public var propertyPrice: String = ""
    @State var email: String = ""
    @State var ownerName: String = ""
    
    @State var alerTitle: String = ""
    @State var showAlert: Bool = false
    
    var body: some View {
        
        NavigationView {
            Form {
                //...
            } //<- End of `Form`
            .navigationBarTitle("Add a New Location")
            
        } //<- End of `NavigationView`
    } //<- End of `body`
    
    func saveButtonPressed() {
        listViewModel.addItem(title: newLocationName, descrip: texts, price: propertyPrice, mail: email, owner: ownerName)
        presentatoinMode.wrappedValue.dismiss()
    }
}

By the way, in Swift, type names should start with Capital letters. You should not use addALandmarkForm as a struct name in Swift.

Function Issue: Closure containing a declaration cannot be used with result builder 'ViewBuilder'
 
 
Q