Search code examples
iosswiftuiswiftui-form

how to track and save the data passed into my view SwiftUI


I am writing a todo list app and Here is my code :

struct TaskItem: View {
@State var task : Task
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
@EnvironmentObject var taskData: UserData
@ObservedObject private var keyboard = KeyboardResponder()
var body: some View {
    Form{
        Section(header: Text("Details").font(.headline)){
            HStack{

                TextField("Title", text: $task.title ).font(Font.headline)

            }
            TextField("Description", text: $task.description)
                .font(Font.body)
        }
        Section{
            Toggle("Mark as Done", isOn: $task.isDone)
        }
        Section{
            Picker(selection: $task.priority, label: Text("priority")) {
                Text("very important").tag(2)
                Text("important").tag(1)
                Text("need to do").tag(0)
            }.pickerStyle(SegmentedPickerStyle()).padding(5)
        }
    }
    .padding(.bottom, keyboard.currentHeight)
    .edgesIgnoringSafeArea(.bottom)
    .animation(.easeOut(duration: 0.16))
    .navigationBarItems(trailing: Button(action: {
        //save data
        var result :[Task]
        result = save(id: self.task.id,
                      creationDate: self.task.creationDate,
                      creationDateYear: self.task.creationDateYear,
                      creationDateMonth: self.task.creationDateMonth,
                      creationDateDay: self.task.creationDateDay,
                      dueDate: self.task.dueDate,
                      time: self.task.time,
                      title: self.task.title,
                      description: self.task.description,
                      priority: self.task.priority,
                      isDone: self.task.isDone, taskData: self.taskData.taskData)
        self.taskData.taskData = result
        self.presentationMode.wrappedValue.dismiss()
    }, label:{
        Text("save")
    }))
    // here I put my save code
}

}

When the save button is pushed, task's var is saved. I want to remove the save button and save data automatically once a value is changed. When I move the block of // save data code out of the save button function and into var body , I get "Function declares an opaque return type, but has no return statements in its body from which to infer an underlying type" Error.

enter code here

enter image description here


Solution

  • var body: some View {
        Form {
        .....
        }
    }
    

    Is what you have now. And this is exactly, what is expected!

    Form {
        .....
    }
    

    is nothing else, just constructor of SwiftUI.Form

    The return statement could be omitted, because it is only one expression.

    var body: some View {
        let somtething = ....
        Form {
            ....
        }
    }
    

    is wrong. Why? Error message explains it very clearly. "Function declares an opaque return type, but has no return statements in its body from which to infer an underlying type"

    This part of error message "Function declares" is a little bit unclear, till you take in the account, what is the difference between function and closure in Swift.

    var body: some View {
        ....
    }
    

    could be rewritten as func statement

    func body()-> some View {
        ...
    }
    

    Maybe, some day, the error messages from compiler will be more clear ...

    If you really like, you can do

    var body: some View {
        let somtething = ....
        return Form {
            ....
        }
    }
    

    I am better to avoid that. For better readability and easy to maintain you code, put all the logic to your model. Use SwiftUI as it was designed for and take an advantage of its declarative syntax.