ゴリポシェブログ

プログラミングやゲームについて気ままに綴ります

【Swift UI】LISTが複数選択と削除が同居できない

Swift UIのリストについての記事です。

UserDefaultに保存されているデータをLISTに表示させ、選択できるような画面を作成しました。
ついでに削除までできたら便利だなぁと考えて調べてみましが、両立させることができませんでした。

最終的にはかなりの力技で実装しました。誰か知ってたら教えて欲しいものです。

①複数選択を可能にする。
→できる。
f:id:GoliraPochette:20210212212611p:plain

ContentView.swiftの一部

 List (selection: $selectionValue) {
  ForEach(item, id: \.self) { item in
                    Text(item)
       }
    }
   <u> .environment(\.editMode, .constant(.active))</u>

②削除可能
→できる。
 左にスワイプしたら削除ボタンが出てきます。
f:id:GoliraPochette:20210212214922p:plain

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