【Swift UI】LISTが複数選択と削除が同居できない
Swift UIのリストについての記事です。
UserDefaultに保存されているデータをLISTに表示させ、選択できるような画面を作成しました。
ついでに削除までできたら便利だなぁと考えて調べてみましが、両立させることができませんでした。
最終的にはかなりの力技で実装しました。誰か知ってたら教えて欲しいものです。
①複数選択を可能にする。
→できる。
ContentView.swiftの一部
List (selection: $selectionValue) { ForEach(item, id: \.self) { item in Text(item) } } <u> .environment(\.editMode, .constant(.active))</u>
②削除可能
→できる。
左にスワイプしたら削除ボタンが出てきます。
List (selection: $selectionValue) { ForEach(item, id: \.self) { item in Text(item) } /// 行削除操作時に呼び出す処理の指定 .onDelete(perform: rowRemove) }
③両立
→色々調べたが、できない。
選択はできるが、スライドしても削除ボタンが出てこない。。
List (selection: $selectionValue) { ForEach(item, id: \.self) { item in Text(item) } /// 行削除操作時に呼び出す処理の指定 .onDelete(perform: rowRemove) } .environment(\.editMode, .constant(.active))
解決策としては、削除ボタンとリストから削除する処理を自前で実装して、乗り越えました。
// // ContentView.swift // olnpickGolfer // // Created by Yosuke Yoshida on 2021/02/09. // import SwiftUI struct ContentView: View { @State private var name = "" @State private var item = getDataName() @State private var isShowingAlert = false @State private var showingAlert = false @State var text: String = "" @State private var selectionValue: Set<String> = [] var body: some View { VStack { TextField("検索", text: $name) .padding() // 入力域のまわりを枠で囲む .textFieldStyle(RoundedBorderTextFieldStyle()) List (selection: $selectionValue) { ForEach(item, id: \.self) { item in Text(item) } } .environment(\.editMode, .constant(.active)) Spacer() HStack { Button("追加") { isShowingAlert = true } .padding() if !item.isEmpty { Button("削除") { rowRemove(delList: selectionValue) selectionValue = [] } .padding() } Spacer() TextFieldAlertView( text: $text, isShowingAlert: $isShowingAlert, placeholder: "", isSecureTextEntry: false, title: "名前登録", message: "名前を入力してください", leftButtonTitle: "キャンセル", rightButtonTitle: "登録", leftButtonAction: nil, rightButtonAction: { if item.contains(text) { alertD() } else { registDataName(name: text) item = getDataName() } } ) .frame(width: 0, height: 0, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/) } } } func rowRemove(delList:Set<String>) { var counter:Int = 0 var isDel = false while counter < item.count { for data in delList { if item[counter] == data { item.remove(at: counter) isDel = true } } if isDel { counter = 0 isDel = false } else { counter+=1 } } reWriteDataName(nameList: item) item = getDataName() } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }