見出し画像

SwiftUIでToDoリストを作ろー! 6

次に動画を参考にデータを追加する部分の仕組みを作っていきます。

AddView()のButtonに機能をつけていきます。

func saveButtonAction(){
}

とボタンの関数を作っておいて

Button(action:saveButtonAction,label:{
   Text("Save")
} )

Buttonのactionの関数を指定します。

saveButtonAction()の中身ですが、ListViewModel()に作っていきます。

func addItem(name:String){
  let newItem = Model(name: name, isComp: false)
  words.append(newItem)
}

Modelで定義したものに引数を入れた変数をつくった変数newItemをデータの配列wordsに追加します。

作った関数をAdd View()の関数saveButtonAction()に追加して引数にこの画面で取得するinputTextを引数に指定して完成です。

func saveButtonAction(){
  listViewModel.addItem(name: inputText)
}

dismiss()

func saveButtonAction(){
  listViewModel.addItem(name: inputText)
   dismiss()
}

を追加してボタンを押して閉じます。この命令を入れる時には

 @Environment(.dismiss) var dismiss

を追加が必要です。

ちなみに参考動画で使っわれているpresentationModeは非推奨となっています。

Deprecated
Use isPresented or dismiss instead.

チェックボックスをタップして完了、未完了を切り替える方法を実装していいます。

ContentViewを修正していきます。リストの1行をタップしたときの挙動なのでListRowView()にモディファイアの.onTapGestureをつけてアニメーションを追加します。

   List{ 
          ForEach(listViewModel.words){ word in
                ListRowView(greet: word) 
                  .onTapGesture {
                        withAnimation(.linear) { 
                            listViewModel.updateItem(word: word)
                  }
         }
  }
        .onDelete(perform: listViewModel.deleteItem)
        .onMove(perform: listViewModel.moveItem)

.onTapGesture {
       withAnimation(.linear) {
                listViewModel.updateItem(word: word)
}

タップした行の完了、未完了の判定をします。

ListViewModel()に判定の関数を書きます。

 func updateItem(word:Model){
        
        if let index = words.firstIndex(where:{$0.id == word.id}){
            words[index] = Model(name: word.name, isComp: !word.isComp) 
        }
        
    }

if letの構文を使って判定します。

firstIndex(where: {条件式})で、条件に合致する値のインデックスを取得する使い方

https://www.choge-blog.com/programming/swiftarrayfirstindex/

条件に合ったインデックスについて

words[index] = Model(name: word.name, isComp: !word.isComp)

"!" で word.isCompを反転させます。trueならfalseへ、falseならばtrueになります。

今までのコード

struct ContentView: View {    
    @EnvironmentObject var listViewModel:ListViewModel
    var body: some View {    
        NavigationStack{
            List{ 
                ForEach(listViewModel.words){ word in
                     ListRowView(greet: word) 
                        .onTapGesture {
                            withAnimation(.linear) { 
                                listViewModel.updateItem(word: word)
                            }
                        }
                }
                .onDelete(perform: listViewModel.deleteItem)
                .onMove(perform: listViewModel.moveItem)
            } 
            .navigationTitle("Todo List")
            .navigationBarItems(
                leading: EditButton(),
                trailing: NavigationLink("Add", destination:AddView())
            )
        }
     }
}
class ListViewModel:ObservableObject{    
    @Published var words:[Model] = [] 
    init(){
        getWord()
    }
    
    func getWord(){
               let newW = [
                 Model(name: "Hello", isComp: true),
                 Model(name: "Good By", isComp: false)
                ]
          words.append(contentsOf: newW)
    }
    
    func deleteItem(indexSet:IndexSet){
        words.remove(atOffsets: indexSet)
    }    
    func moveItem(from: IndexSet,to: Int){
        words.move(fromOffsets: from, toOffset: to)
    }
    
    func addItem(name:String){
        let newItem = Model(name: name, isComp: false)
        words.append(newItem)
    }
    
    func updateItem(word:Model){        
        if let index = words.firstIndex(where:{$0.id == word.id}){
            words[index] = Model(name: word.name, isComp: !word.isComp) 
        }
    }
}

この記事が気に入ったらサポートをしてみませんか?