web-dev-qa-db-fra.com

SwiftUI - Plusieurs boutons dans une ligne de liste

Disons que j'ai un List et deux boutons sur une ligne, comment distinguer quel bouton est tapé sans mettre en surbrillance la ligne entière?

Pour cet exemple de code, lorsque l'un des boutons de la ligne est tapé, les rappels d'action des deux boutons sont appelés.

// 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

Vous devez utiliser 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

Semble être un problème spécifique concernant Button lorsqu'il est contenu dans une ligne List.

Solution:

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

Cela donne la sortie souhaitée.

Vous pouvez également utiliser un Group au lieu de Text pour avoir un design sophistiqué pour les "boutons".

17
Matteo Pacini

L'une des différences avec SwiftUI est que vous ne créez pas d'instances spécifiques de, par exemple UIButton, car vous pourriez être dans une application Mac. Avec SwiftUI, vous demandez une chose de type bouton.

Dans ce cas, puisque vous êtes dans une ligne de liste, le système vous donne une taille réelle, appuyez n'importe où pour déclencher l'action, bouton. Et puisque vous en avez ajouté deux, les deux sont déclenchés lorsque vous appuyez n'importe où.

Vous pouvez ajouter deux vues distinctes et leur donner un .onTapGesture pour les faire agir essentiellement comme des boutons, mais vous perdriez le tap tap de la ligne de cellule et tout autre bouton automatique comme les fonctionnalités que SwiftUI donnerait.

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

        Spacer()

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

Vous devez créer votre propre 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