MENU

【SwiftUI】Listのひとつの要素に複数のボタンを設置する

目次

何が問題か?

タイトルを読んだ限り簡単に実現できそうですよね?
実は、そうでもないのです。

素直に実装した例です。

  • コード
import SwiftUI

struct ContentView: View {
    let items = ["Item 1", "Item 2", "Item 3"] // 仮のデータ
    
    var body: some View {
        List {
            ForEach(items, id: \.self) { item in
                VStack {
                    Text(item)
                        .padding()
                    HStack {
                        Button(action: {
                            print("\(item) Button 1 tapped")
                        }) {
                            Text("Button 1")
                                .padding()
                                .background(Color.blue)
                                .foregroundColor(.white)
                                .cornerRadius(8)
                        }
                        Button(action: {
                            print("\(item) Button 2 tapped")
                        }) {
                            Text("Button 2")
                                .padding()
                                .background(Color.red)
                                .foregroundColor(.white)
                                .cornerRadius(8)
                        }
                        // 必要なだけボタンを追加
                    }
                }
                .padding()
                .background(Color.gray.opacity(0.1))
                .cornerRadius(8)
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
  • 実行結果
    btnonList.gif

ボタンが識別されていない(T . T)
Item1Button1を押しているのに、となりのButton2までおされていることになっています、、、

対処法

  • 原因
    タップ領域が原因です。
    Listをそのまま実装すると、ひとつの要素にタップ領域はその要素の中全部です。今回の場合はbutton1とbutton2の両方が同じタップ領域となっています。
  • 結論
    buttonStyleのborderless修飾子を使用しましょう!
  • 修正後のコード
import SwiftUI

struct ButtonOnList: View {
    let items = ["Item 1", "Item 2", "Item 3"] // 仮のデータ

    var body: some View {
        List {
            ForEach(items, id: \.self) { item in
                VStack {
                    Text(item)
                        .padding()
                    HStack {
                        Button(action: {
                            print("\(item) Button 1 tapped")
                        }) {
                            Text("Button 1")
                                .padding()
                                .background(Color.blue)
                                .foregroundColor(.white)
                                .cornerRadius(8)
                        }
                        .buttonStyle(.borderless) // これを追加
                        Button(action: {
                            print("\(item) Button 2 tapped")
                        }) {
                            Text("Button 2")
                                .padding()
                                .background(Color.red)
                                .foregroundColor(.white)
                                .cornerRadius(8)
                        }
                        .buttonStyle(.borderless) // これを追加
                        // 必要なだけボタンを追加
                    }
                }
                .padding()
                .background(Color.gray.opacity(0.1))
                .cornerRadius(8)
            }
        }
    }
}

struct ButtonOnList_Previews: PreviewProvider {
    static var previews: some View {
        ButtonOnList()
    }
}
  • 実行結果
    after.gif
    無事に同じ要素の中でもボタンが識別されるようになりました!

最後に

もしよければいいねや保存をお願いします!
エンジニアライフの励みになります(^O^)/

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

Rio@iOSエンジニアのアバター Rio@iOSエンジニア 経営者兼モバイルアプリエンジニア

都内のモバイルアプリ開発会社経営者。
モバイルアプリの新規の請負開発及び保守運用を引き受ける。
Denso→Honda→現在
#RxSwift #MVVM #Firebase #Python3

コメント

コメントする

目次