見出し画像

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

行の削除、追加の機能をつけます。モディファイアを使います。

    List{ 
            ForEach(words){ word in
                  ListRowView(greet: word) 
      }
         .onDelete(perform: deleteItem)
         .onMove(perform: moveItem)

.onDelete(perform: deleteItem)
.onMove(perform: moveItem)

関数の中身
まず削除の関数。

  func deleteItem(indexSet:IndexSet){
        words.remove(atOffsets: indexSet)
   }    

移動の関数

  func moveItem(from: IndexSet,to: Int){
        words.move(fromOffsets: from, toOffset: to)
  }

Editボタンを押すと

と表示できるようになります。

次にContentViewには表示する時に部品となるものも実装されているのでその部品となるものをListViewModelとして別定義します。

@PublishedはObservableObjectプロトコルに準拠したクラス内のプロパティに変化があった際にViewに対して通知を行う役目があります。@Stateに近い機能。

ListViewModelを別画面でも使えるように

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(ListViewModel())
        }
    }
}

.environmentObject(ListViewModel())

を追加します。このままではエラーが出ます。ListViewModelはObservableObject準拠の必要があるので

class ListViewModel:ObservableObject{}

とします。そしてContentViewから表示するコード以外をこちらに移します。

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)
    }

}

それではContentView()を作ったListViewModelを使った仕様に変えていきます。

@EnvironmentObject var listViewModel:ListViewModel

リスト表示するもとになり配列を取得するために@EnvironmentObjectで変数を宣言します。

    @State var words:[Model] = [
        Model(name: "Hello", isComp: true),
        Model(name: "Good By", isComp: false)
    ]

は必要がなくなるので削除します。

ForEachの部分も宣言したlistViewModelからデータを取れるようにします。

ForEach(listViewModel.words){ word in
     ListRowView(greet: word)
}

そして編集を有効にする部分も同じくlistViewModelのメソッド、関数を使うようにします。

.onDelete(perform: listViewModel.deleteItem)
.onMove(perform: listViewModel.moveItem)

必要無くなった

    func deleteItem(indexSet:IndexSet){
        words.remove(atOffsets: indexSet)
     }    
    func moveItem(from: IndexSet,to: Int){
        words.move(fromOffsets: from, toOffset: to)
    }

を削除します。

ここまでの最終的なコードです。

struct ContentView: View {
    
    @EnvironmentObject var listViewModel:ListViewModel

    var body: some View {
        
        NavigationStack{
            List{ 
                ForEach(listViewModel.words){ word in
               
                    ListRowView(greet: word) 
                }
                .onDelete(perform: listViewModel.deleteItem)
                .onMove(perform: listViewModel.moveItem)
            } 
            .navigationTitle("Todo List")
            .navigationBarItems(
                leading: EditButton(),
                trailing: NavigationLink("Add", destination:AddView())
            )
        }
     } 
}

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