skip to Main Content

So I have this structure Task which has a @State completion:

struct Task:Identifiable{
    var id: Int
    @State var completion:Bool = false
    var priority:String? = nil
    @State var completionDate:Date? = nil
    var creationDate:Date
    var fullDescription:String
}

In a TaskItem:View I’m trying to make a checkbox that will update the state properly:

struct TaskItem: View {
    
    @State var task:Task
    @State var isChecked:Bool = false
    
    func toggle(){
        isChecked = !isChecked
        task.completion = isChecked
        if isChecked {
            task.completionDate = Date()
        } else {
            task.completionDate = nil
        }
    }
    
    var body: some View {
       
                    Button(action: toggle){
                        
                       Image(systemName: isChecked ? "square.split.diagonal.2x2": "square")
                        
      
            
            
        }
        
    }
}

But even though isChecked changes and the image as well, the task.completion doesn’t. How can I fix this?

I’m currently using this to view it:

struct TaskItem_Previews: PreviewProvider {
    static var previews: some View {
        let task =  testTask()
        TaskItem(task: task)
    }
}

2

Answers


  1. The @State property wrapper is NOT meant to be used inside a data model, like your struct Task. The @State property wrapper is a property wrapper meant to be used on SwiftUI Views. If you remove @State, you should be in good shape.

    Login or Signup to reply.
  2. Do not use @State outside a View like you have in Task. They are only to be used inside a View.

    The docs explaining @State is quite useful:

    "… You should only access a state property from inside the view’s body, or from methods called by it.
    For this reason, declare your state properties as private, to prevent clients of your view from accessing them.
    It is safe to mutate state properties from any thread….".

    Note: that Swift also has a Task struct, that is a unit of asynchronous work. This may become a problem
    if you use the same name for your Task struct.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search