BLACK FRIDAY SALE: Save big on all my Swift books and bundles! >>

Create an editDetailView

Forums > SwiftUI

I have an app and want to add an edit page for the detailView. To do that I build a simulair view like the add view. It's something like this:

@State private var name = ""

var body: some View {
    Form {
        TextField("Name", text: $name)
    }
}

And off course it has some functions and such but that is inrelivant i think.

What I want is that I'm able to edit the text like in your iphones contact app. So the data/text is already in the textfield, ready to be edited.

I have to mention that the data is stored in CoreData.

   

The Edit view needs a property to store the Core Data entity so you can fill the view with the appropriate data from the entity. Core Data uses classes so you would use the @StateObject property wrapper.

@StateObject var model: Model

Where Model is the name of your Core Data entity.

Now you can fill the text field from the entity.

TextField("Name", text: $model.name)

You'll also have to pass the entity to the Edit view when making the call to show the Edit view.

   

If I do that i get "Cannot convert value of type 'Binding<String?>' to expected argument type 'Binding<String>'"

   

@Bnerd  

Give your optional a default value:

TextField("Name", text: $model.name ?? "text")

   

That doesn't work. You want to replace a binding to a empty string. You can't use this somewhere else to save it.

Error messages: Cannot convert value of type 'String' to expected argument type 'Binding<String?>' Cannot convert value of type 'Binding<String?>' to expected argument type 'Binding<String>'

   

@Bnerd  

Does the below work?

struct DetailView: View {

    @StateObject var model: Marteen
    @State private var name: String = "Text"

    var body: some View {
        TextField("Name", text: $name).onChange(of: name) { newValue in
            model.name = newValue
        }
    }
}

   

In my case this gives a empty textfield.

struct ContactDetailEditView: View {

    @StateObject var model: ContactEntity

    @State private var firstName: String = ""

    var body: some View {
        TextField("First Name", text: $firstName)
            .onChange(of: firstName) { newValue in
            contact.firstName = newValue
        }
    }
}

   

@Bnerd  

Why you are using ?

contact.firstName = newValue

Whereas you made an instance of a

@StateObject var model: ContactEntity

it should be

model.firstName = newValue

I tried the code I sent you before and it works, everytime you type in the textfield the model.name is updated. Add a print in the OnChange to verify.

   

Because i made a type with re typing it here.

But it doesn't change enything.

I just found a solution for it.

struct ContactDetailEditView: View {

    @StateObject var model: ContactEntity

//    let contact: ContactEntity

    @State private var firstName: String = ""

    var body: some View {

        TextField("First Name", text: $firstName)
            .onAppear {
                DispatchQueue.main.asyncAfter(deadline: .now()){
                    firstName = model.firstName ?? ""
                }
            }
            .onChange(of: firstName) { newValue in
            model.firstName = newValue
        }
    }
}

credits to: link

   

Hacking with Swift is sponsored by RevenueCat

SPONSORED In-app subscriptions are a pain to implement, hard to test, and full of edge cases. RevenueCat makes it straightforward and reliable so you can get back to building your app. Oh, and it's free if your app makes less than $10k/mo.

Learn more

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.