1

I am working on a list app and would like the ability to edit the list item details. I am using CoreData for the data model. Right now I am stuck on how to pass the data item from the DetailView to the EditItemView. I updated to the code to the current state I am at. I am currently getting an error in the DetailView taged to the DetailView(myItem: item) line the preview. Am I setting the @State correctly for name and passing the @Binding correctly? I think my error lies in the way I am passing the name in EditItemView(name: self.$name) to the edit view. Thoughts?

Detail View:

import CoreData
import SwiftUI

struct DetailView: View {
    @Environment(\.managedObjectContext) var moc
    @ObservedObject var myItem: Item

    @State private var name: String
    @State private var showingEditScreen = false

    var body: some View {
        NavigationView {
            VStack {
                Text(self.myItem.name ?? "Unknown Item")
                Text(self.myItem.attribute ?? "Unknown attribute")
            }
        }
        .navigationBarTitle(Text(myItem.name ?? "Unknown Item"), displayMode: .inline)
        .navigationBarItems(trailing:
            Button(action: {
                self.showingEditScreen.toggle()
            }) {
                Image(systemName: "square.and.pencil")
            }
        )
        .sheet(isPresented: $showingEditScreen) {
            EditItemView(name: self.$name).environment(\.managedObjectContext, self.moc)
        }
    }
}

struct DetailView_Previews: PreviewProvider {
    static let moc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)

    static var previews: some View {
        let item = Item(context: moc)
        item.name = "Test item"
        item.attribute = "Test attribute"

        return NavigationView {
            DetailView(myItem: item)
        }
    }
}

Edit Item View:

import CoreData
import SwiftUI

struct EditItemView: View {
    @Binding var name: String

    var body: some View {
        TextField("Enter Item Name", text: self.$name)
    }
}

struct EditItemView_Previews: PreviewProvider {
    static var previews: some View {
        EditItemView(name: .constant("ItemX"))
    }
}
3
  • I updated the code in the post. Still getting errors. Commented Feb 20, 2020 at 15:50
  • The build error I am getting is: Cannot invoke initializer for type 'DetailView' with an argument list of type '(myItem: Item)' Commented Feb 20, 2020 at 20:06
  • It will build if I comment out @State private var name: String and .sheet(isPresented: $showingEditScreen) {EditItemView(name: self.$name).environment(\.managedObjectContext, self.moc)} in the Detail View. I really can't figure out what is the correct syntax to pass the data to the next view. Commented Feb 20, 2020 at 20:26

1 Answer 1

3

I would say the Item or a NSManagedObject is an ObservableObject.

so you can directly use an item in a View:

 struct EditItemView: View  {

     @ObservedObject var myItem : Item

      var body: some View {
       ...}

 }
Sign up to request clarification or add additional context in comments.

2 Comments

Missed that. Added but still does not allow me to build and send the item to the edit screen.
Oh, I missed that you were talking about in EditItemView. I got it now. Once I setup the new @ObservedObject in the EditItemView and used that name in the DetailView to pass the data, it worked great. Thanks so much for the help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.