LoginSignup
hajimeapp
@hajimeapp

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

【SwiftUI】List内に複数Buttonを設置しても、一つしかButtonが反応しない

解決したいこと

簡単なToDoリストを作成しています!
仕様としては、

①リストのテキスト部分をタップするとやったことリストに移動する
②リスト右の「🗑」をタップすると削除される
③ローカル保存にはCoreDataを使用

を予定しています!(下記イメージ画像になります!)

IMG_8202.jpg

そのため、リスト内にはHStackで

□ → 完了ボタン(=テキスト) → 削除ボタン(=🗑マーク)

という順番に配置しております!

しかし、リスト内のどの箇所をタップしても削除ボタンしか反応せず...。削除ボタンを外すと完了ボタンが反応するようになりました。

もしかしてリスト内ではButtonは一つしか適応されず、HStackの一番右のButtonのみが適応されているかも?と思い、今回ご質問させていただきました!

該当するコードは以下になります!どなたかご存知の方がいらっしゃいましたら、どうかコメントいただけますと幸いです!🙇

struct ToDoView: View {
    //「やること」リストはCoreDataでローカル保存されるように実装しています
    //Entityは「ToDo」、Attributeは「completed」「timestamp」「title」の3つ
    //「completed」→やることが完了したか否かを保存
    //「timestamp」→追加した時間を保存(追加順にリストに表示されるために用いる)
    //「title」→やることのTextを保存
    @Environment(\.managedObjectContext) var toDoData
    @FetchRequest(sortDescriptors: [NSSortDescriptor(keyPath: \ToDo.timestamp, ascending: false)]) var toDoList: FetchedResults<ToDo>
    @State var inputText = ""
    var body: some View {
        VStack {
            List {
                ForEach(toDoList) { toDo in
                    if !(toDo.completed) {
                        HStack {
                            if (toDo.completed) {
                                Text("☑")
                                    .font(.title)
                                    .foregroundColor(.gray)
                            } else {
                                Text("□")
                                    .font(.title)
                                    .foregroundColor(.gray)
                            }
                            Button {
                                completeToDo(toDo: toDo)
                            } label: {
                                Text(toDo.title!)
                            }
                            Button {
                                deleteToDo(toDo: toDo)
                            } label: {
                                Image(systemName: "trash")
                                    .foregroundColor(.gray)
                            }
                        }
                    }
                }
            }
            .listStyle(.plain)
            Spacer()
            TextField("やることを追加", text: $inputText, prompt: Text("やることを追加").foregroundColor(.gray))
                .textFieldStyle(.roundedBorder)
                .onSubmit {
                    if inputText != "" {
                        addToDo()
                    }
                }
        }
    }
    
    func addToDo() {
        let newToDo = ToDo(context: toDoData)
        newToDo.title = inputText
        newToDo.timestamp = Date()
        do {
            try toDoData.save()
        } catch {
            fatalError("セーブに失敗")
        }
        inputText = ""
    }
    
    func completeToDo(toDo: ToDo) {
        toDo.completed.toggle()
            do {
                try toDoData.save()
            } catch {
                fatalError("セーブに失敗")
            }
    }
    
  func deleteToDo(toDo: ToDo) {
      toDoData.delete(toDo)
      do {
          try toDoData.save()
      } catch {
          fatalError("セーブに失敗")
      }
  }
}
0

1Answer

もしかしてリスト内ではButtonは一つしか適応されず、HStackの一番右のButtonのみが適応されているかも?

そんなことはありません。
上のコードを実行すると、completeToDoとdeleteToDoの両方が呼ばれています。
原因は↓こちらだと思います。

0Like

Comments

  1. @hajimeapp

    Questioner

    @nak435

    こちらもコメントいただきありがとうございます!

    たしかに上記方法で消えました!ただ原因があまり理解できておらずでして、、、

    こちらって、completeToDoもdeleteToDoも実行されて、結果としてList自体から消えているという状態でしょうか?

    ・Listのイベントとは何か?(Listがタップされることで、List内のボタン全ての処理が実行されてしまう?)
    ・なぜボタンのスタイルを変更するとListのイベントが発生しなくなるのか

    あたりもまだわかっておらず、、、もし可能でしたらご教示いただけますと幸いです...🙇

Your answer might help someone💌