97 votes

SwiftUI ne peut pas taper dans l'espaceur de HStack

J'ai une vue Liste et chaque ligne de la liste contient une HStack avec quelques vues de texte et une image, comme ceci :

HStack{
    Text(group.name)
    Spacer()
    if (groupModel.required) { Text("Required").color(Color.gray) }
    Image("ic_collapse").renderingMode(.template).rotationEffect(Angle(degrees: 90)).foregroundColor(Color.gray)
}.tapAction { self.groupSelected(self.group) }

Cela semble fonctionner parfaitement, sauf lorsque je tape dans la section vide entre mon texte et l'image (là où le bouton Spacer() est) l'action de tapotement n'est pas enregistrée. L'action de toucher ne se produit que lorsque je touche le texte ou l'image.

Quelqu'un d'autre a-t-il rencontré ce problème / connaît-il une solution de contournement ?

226voto

hnh Points 729

Comme je l'ai appris récemment, il y en a aussi :

HStack {
  ...
}
.contentShape(Rectangle())
.onTapGesture { ... }

Ça marche bien pour moi.

19voto

rob mayoff Points 124153

Pourquoi ne pas simplement utiliser un Button ?

Button(action: { self.groupSelected(self.group) }) {
    HStack {
        Text(group.name)
        Spacer()
        if (groupModel.required) { Text("Required").color(Color.gray) }
        Image("ic_collapse").renderingMode(.template).rotationEffect(Angle(degrees: 90)).foregroundColor(Color.gray)
    }
}.foregroundColor(.primary)

Si vous ne souhaitez pas que le bouton applique la couleur d'accentuation à l'élément Text(group.name) vous devez définir le foregroundColor comme je l'ai fait dans mon exemple.

9voto

Asi Givati Points 457

Fonctionne comme par magie sur chaque vue :

extension View {
        func onTapGestureForced(count: Int = 1, perform action: @escaping () -> Void) -> some View {
            self
                .contentShape(Rectangle())
                .onTapGesture(count:count, perform:action)
        }
    }

7voto

Jim Marquardt Points 1712

J'ai pu contourner ce problème en enveloppant l'espaceur dans un ZStack et en ajoutant une couleur solide avec une très faible opacité :

ZStack {
    Color.black.opacity(0.001)
    Spacer()
}

6voto

Casper Zandbergen Points 607

Extension simple basée sur la réponse de Jim

extension Spacer {
    /// https://stackoverflow.com/a/57416760/3393964
    public func onTapGesture(count: Int = 1, perform action: @escaping () -> Void) -> some View {
        ZStack {
            Color.black.opacity(0.001).onTapGesture(count: count, perform: action)
            self
        }
    }
}

Maintenant, cela fonctionne

Spacer().onTapGesture {
    // do something
}

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