51 votes

SwiftUI - Plusieurs boutons dans une ligne de liste

Disons que j'ai un List et deux boutons dans une rangée, comment distinguer le bouton sur lequel on a appuyé sans que la rangée entière ne soit mise en évidence ?

Dans cet exemple de code, lorsque l'un des boutons de la rangée est touché, les rappels d'action des deux boutons sont invoqué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"

85voto

Ramis Points 610

Vous devez utiliser BorderlessButtonStyle() o PlainButtonStyle() .

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

            Button(action: { print("Button at \(row)") }) {
                Text("Row: \(row) Name: B")
            }
            .buttonStyle(PlainButtonStyle())
        }
    }

22voto

Matteo Pacini Points 2704

Il semble que ce soit un problème spécifique concernant Button lorsqu'il est contenu dans un List rang.

Solution de rechange :

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

On obtient ainsi le résultat souhaité.

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

6voto

Jonathan Bennett Points 855

L'une des différences avec SwiftUI est que vous ne créez pas d'instances spécifiques de UIButton, par exemple, comme vous le feriez dans une application Mac. Avec SwiftUI, vous demandez un objet de type bouton.

Dans ce cas, étant donné que vous vous trouvez dans une ligne de liste, le système vous propose un bouton de taille normale (touchez n'importe où pour déclencher l'action). Et comme 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 une .onTapGesture pour qu'ils agissent essentiellement comme des boutons, mais vous perdriez le clignotement de la rangée de cellules et toute autre fonctionnalité de bouton automatique que SwiftUI pourrait offrir.

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

        Spacer()

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

3voto

Anton Points 1276

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

-6voto

SwiftUI est toujours en version bêta. Vous devez signaler ce problème via l'assistant de commentaires : http://feedbackassistant.apple.com/

Très probablement un bug dans leur système.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X