Home > Software engineering >  I'm trying to make the input entered from the textfield the new name of my list when the save b
I'm trying to make the input entered from the textfield the new name of my list when the save b

Time:01-30

I can't find how to get user input and update my name on the TodoListView All code below . Nothing much but i can't make it. (in my model i have id=UUID and name=String)

ChangeTodoView(On this view i try to get users input and change the value)

struct ChangeTodoView: View {
@State var not: String
@ObservedObject var todoVM = TodoListViewModel()
init(not: String){
    self.not = not
}

var body: some View {
        VStack{
            Text("Enter Your Note")
                .foregroundColor(Color.gray)
            Spacer(minLength: 30)
            Form {
                TextEditor(text: $not)
                        Button(action: {
                           // todoVM.items[1] = not
                            //
                            
                            todoVM.rename(indexSet: , not: not)
                        }, label: {
                            Text("Save")
                        }).disabled(not.isEmpty)
                    }
            
        }            
}

TodoListView(on this page i open ChangeTodoView)

struct ToDoListView: View {
@ObservedObject var todoVM = TodoListViewModel()
var body: some View {
    NavigationView{
        List{
            ForEach(todoVM.items){item in
                NavigationLink(
                    destination: ChangeTodoView(not: ""),
                        label : {
                            Text(item.name)
                        })
                
                    }            
            }
        .navigationTitle("Todo App")
        .navigationBarTitleDisplayMode(.large)
            .toolbar {
                ToolbarItemGroup(placement: .navigationBarTrailing){
                    EditButton()
                    Button {
                        todoVM.addItem()
                    } label: {
                        Image(systemName: "plus")
                    }

                }
            }
    }
    
   
    }
}

TodoListViewModel(rename function is my updating function. i try to get index and change that name to new name )

class TodoListViewModel: ObservableObject{
@Published var items = [Item(id: UUID(), name: "note1"), Item(id: UUID(), name: "note2"), Item(id: UUID(), name: "note3")]

init(){
    
    
}
func rename(indexSet: IndexSet, not: String) -> String{
    for index in indexSet{
        items[index].name = not
    }
    return not
    
}

}

CodePudding user response:

The most important change that has to happen is that you have to pass a single instance of the TodoListViewModel between your views. Right now, because you're creating a second instance of it in ChangeTodoView, your changes never get back to the original parent view (which, again, has a different instance of the view model).

I had to make a couple of other changes to your code because there was information left out about your indexSet and how you were deriving that, but that's all secondary to the issue of the single instance of the view model (so, make sure your only use TodoListViewModel() once).

struct Item : Identifiable {
    var id: UUID
    var name: String
}

class TodoListViewModel: ObservableObject{
    @Published var items = [Item(id: UUID(), name: "note1"), Item(id: UUID(), name: "note2"), Item(id: UUID(), name: "note3")]
    func rename(id: UUID, not: String) {
        items = items.map { item -> Item in
            if item.id == id {
                var copy = item
                copy.name = not
                return copy
            } else {
                return item
            }
        }
    }
}

struct ToDoListView: View {
    @ObservedObject var todoVM = TodoListViewModel()
    var body: some View {
        NavigationView{
            List{
                ForEach(todoVM.items){ item in
                    NavigationLink(
                        destination: ChangeTodoView(id: item.id, not: "", todoVM: todoVM), //<-- pass the instance
                        label : {
                            Text(item.name)
                        })
                }
            }
        }
    }
}

struct ChangeTodoView: View {
    var id: UUID
    @State var not : String
    @ObservedObject var todoVM : TodoListViewModel //<-- Passed from parent view
    
    var body: some View {
        VStack{
            Text("Enter Your Note")
                .foregroundColor(Color.gray)
            Spacer(minLength: 30)
            Form {
                TextEditor(text: $not)
                Button(action: {
                    todoVM.rename(id: id, not: not)
                }, label: {
                    Text("Save")
                }).disabled(not.isEmpty)
            }
        }
    }
}
  •  Tags:  
  • Related