web-dev-qa-db-ja.com

SwiftUI-リスト行の複数のボタン

1つの行にListと2つのボタンがあるとします。行全体を強調表示せずに、どのボタンがタップされたかを区別するにはどうすればよいですか?

このサンプルコードでは、行のいずれかのボタンがタップされると、両方のボタンのアクションコールバックが呼び出されます。

// a simple list with just one row
List {

    // both buttons in a HStack so that they appear in a single row
    HStack {
        Button(action: {
            print("button 1 tapped")
        }) {
            Text("One")
        }

        Button(action: {
            print("button 2 tapped")
        }) {
            Text("Two")
        }
    }
}

// when tapping just once on either button:
// "button 1 tapped"
// "button 2 tapped"
27
Bradley Mackey

BordlessButtonStyle()を使用する必要があります。

List([1, 2, 3], id: \.self) { row in
    HStack {
        Button(action: {
            print("Buton at \(row) with name A")
        }) {
            Text("Row: \(row)" + " Name: A")
        }.buttonStyle(BorderlessButtonStyle())
        Button(action: {
            print("Buton at \(row) with name B")
        }) {
            Text("Row: \(row)" + " Name: B")
        }.buttonStyle(BorderlessButtonStyle())
    }
}
12
Ramis

Button行に含まれる場合、Listに関する特定の問題のようです。

回避策

List {
  HStack {
    Text("One").onTapGesture { print("One") }
    Text("Two").onTapGesture { print("Two") }
  }
}

これにより、目的の出力が得られます。

Groupの代わりにTextを使用して、「ボタン」の洗練されたデザインを作成することもできます。

17
Matteo Pacini

SwiftUIとの違いの1つは、Macアプリを使用している可能性があるため、UIButtonなどの特定のインスタンスを作成しないことです。 SwiftUIでは、ボタンタイプのものを要求しています。

この場合、リストの行にいるので、システムはフルサイズを提供し、どこかをタップしてアクション、ボタンをトリガーします。 2つ追加したので、どこかをタップすると両方がトリガーされます。

2つの個別のビューを追加して、それらに.onTapGestureそれらを基本的にボタンとして機能させるには、セル行のタップフラッシュや、SwiftUIが提供する機能のような他の自動ボタンを失うことになります。

List {
    HStack {
        Text("One").onTapGesture {
            print("Button 1 tapped")
        }

        Spacer()

        Text("Two").onTapGesture {
            print("Button 2 tapped")
        }
    }
}
6

独自のButtonStyleを作成する必要があります。

  struct MyButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
      configuration.label
        .foregroundColor(.accentColor)
        .opacity(configuration.isPressed ? 0.5 : 1.0)
    }
  }

  struct IdentifiableString: Identifiable {
    let text: String
    var id: String { text }
  }

  struct Test: View {
    var body: some View {
      List([
        IdentifiableString(text: "Line 1"),
        IdentifiableString(text: "Line 2"),
      ]) {
        item in
        HStack {
          Text("\(item.text)")
          Spacer()
          Button(action: { print("\(item.text) 1")}) {
            Text("Button 1")
          }
          Button(action: { print("\(item.text) 2")}) {
            Text("Button 2")
          }
        }
      }.buttonStyle(MyButtonStyle())
    }
  }
2
Anton