Search code examples
swiftswiftuiswiftui-foreachswiftui-button

While using an if statement: Type '()' cannot conform to 'View'; only struct/enum/class types can conform to protocols


I am trying to implement a button that activates a ForEach loop to go through each item in the list and mark it as delayed. This is my code:

import SwiftUI

struct AllJobsDelayWeather: View{
    var jobIndividualViewModel: JobIndividualViewModel
    @State public var comparisonDate = getCurrentDate()
    
    
    var body: some View{
        let jobDate = ParserDate(date: jobIndividualViewModel.job.date)
        Text(" ")
        if jobIndividualViewModel.job.completed == false && jobDate == comparisonDate{ //error is here
            jobIndividualViewModel.delayWeather(jobIndividualViewModel.job) 
               Text(" ")
            }
        Text(" ")
        
        }
}

This is in the "main" (if you can call it) portion of the program

Button("Delay Bad Weather"){
                    ForEach(jobViewModel.jobIndividualViewModels) { jobVM in
                        AllJobsDelayWeather(jobIndividualViewModel: jobVM)
                    }
                }.padding()

I am getting this error: Type '()' cannot conform to 'View'; only struct/enum/class types can conform to protocols. The function works and has been "ad hoc" tested. I don't know how to get rid of the error that the compiler is throwing.

EDIT Currently trying to do this:

//in body
Button("Delay Bad Weather"){
                    ForEach(jobViewModel.jobIndividualViewModels) { jobVM 
//errors getting thrown above
                        AllJobDelayWeather(jobVM: jobVM)
                    }
                }.padding()

//outside if struct in the same file

func AllJobDelayWeather(jobVM: JobIndividualViewModel){
    let comparisonDate = getCurrentDate()
    
    let jobDate = ParserDate(date: jobVM.job.date)
    if jobVM.job.completed == false && jobDate == comparisonDate{
        jobVM.delayWeather(jobVM.job)

        }
    
}

I am now getting 2 instances of the error, one on the F of ForEach and the { before the first instance of jobVM.


Solution

  • As mentioned in the comments, you're using ForEach, which is a SwiftUI view, inside a Button's action closure, where you can't have views. Looking at your updated code, it looks like you just want a regular forEach. Something like:

    Button("Delay Bad Weather") {
       jobViewModel.jobIndividualViewModels.forEach { jobVM
         allJobDelayWeather(jobVM: jobVM)
       }
    }.padding()
    
    func allJobDelayWeather(jobVM: JobIndividualViewModel){
        let comparisonDate = getCurrentDate()
        
        let jobDate = ParserDate(date: jobVM.job.date)
        if jobVM.job.completed == false && jobDate == comparisonDate{
            jobVM.delayWeather(jobVM.job)
        }
    }
    

    I changed your function name to lowercase because that's the preferred naming convention in Swift. It's also somewhat unusual to have a function floating outside of a view like you imply in your comments -- it probably belongs inside the view or inside the view model (hard to say since I can't see all of your code).