web-dev-qa-db-fra.com

Pouvez-vous associer un UIGestureRecognizer à plusieurs vues?

UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)];
[self.view1 addGestureRecognizer:tapGesture];
[self.view2 addGestureRecognizer:tapGesture];
[tapGesture release];

Dans le code ci-dessus, tapez seulement sur view2 sont reconnus. Si je commente la troisième ligne, puis tape sur view1 sont reconnus. Si j'ai raison et que vous ne pouvez utiliser qu'un seul identifiant de geste, je ne suis pas sûr qu'il s'agisse d'un bogue ou s'il nécessite simplement de la documentation supplémentaire.

218
kubi

Un UIGestureRecognizer doit être utilisé avec une seule vue. Je suis d'accord que la documentation est inégale. Ce UIGestureRecognizer a une seule propriété view le donne:

vue

La vue à laquelle la reconnaissance de geste est attachée. (lecture seulement)

@property (nonatomic, en lecture seule) UIView * view

Discussion Vous attachez (ou ajoutez) une reconnaissance de geste à un objet UIView à l'aide de la méthode addGestureRecognizer:.

317
TomSwift

Je l'ai contourné en utilisant ce qui suit.

for (UIButton *aButton in myButtons) {

            UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
            longPress.minimumPressDuration=1.0;
            [aButton addGestureRecognizer:longPress];
            [longPress release];

}

Ensuite, dans ma méthode handleLongPress, je viens de définir un UIButton égal à la vue du programme de reconnaissance de gestes et de créer une branche pour ce que je fais en fonction de ce bouton.

- (void)handleLongPress:(UILongPressGestureRecognizer*)gesture {
    if ( gesture.state == UIGestureRecognizerStateEnded ) {
        UIButton *whichButton=(UIButton *)[gesture view];
        selectedButton=(UIButton *)[gesture view];
    ....
}
48
kwalker

Pour Swift 3 au cas où quelqu'un le demanderait: basé sur la réponse de Bhavik Rathod ci-dessus.

 func setGestureRecognizer() -> UIPanGestureRecognizer {

        var panRecognizer = UIPanGestureRecognizer()

        panRecognizer = UIPanGestureRecognizer (target: self, action: #selector(pan(panGesture:)))
        panRecognizer.minimumNumberOfTouches = 1
        panRecognizer.maximumNumberOfTouches = 1
        return panRecognizer
    }

        ///set the recognize in multiple views
        view1.addGestureRecognizer(setGestureRecognizer())
        view2.addGestureRecognizer(setGestureRecognizer())
18
George Asda

Non, vous ne devez pas associer de reconnaissance de geste à plusieurs vues.

Il y a ces informations explicites dans la documentation Apple):

Des reconnaisseurs de geste sont associés à une vue

Chaque identificateur de geste est associé à une vue. En revanche, une vue peut avoir plusieurs identificateurs de gestes, car une seule vue peut répondre à de nombreux gestes différents. Pour qu'un identificateur de mouvements reconnaisse les touches se produisant dans une vue particulière, vous devez associer le dispositif de reconnaissance de gestes à cette vue.

Guide de gestion des événements pour iOS - Reconnaissance de gestes Apple Developer Library

Comme d'autres l'ont mentionné, ils pourraient fonctionner dans certains cas, cela va clairement à l'encontre de la documentation et pourrait changer dans les futures versions d'iOS.

Ce que vous pouvez faire est d’ajouter des identificateurs de geste séparés aux vues que vous souhaitez surveiller et ils peuvent partager une action commune.

8
Joseph Lord

On peut faire quelque chose Comme ça, c'est facile et simple

1) créer une fonction comme ci-dessous dans votre contrôleur (cette fonction renverra GestureRecognizer)

-(UITapGestureRecognizer*)setRecognizer{
     UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(openProfile)];
     [gestureRecognizer setNumberOfTapsRequired:1];
     return gestureRecognizer;
}

2) maintenant définir cette reconnaissance dans plusieurs vues

[self.view1 addGestureRecognizer:[self setRecognizer]]; 
[self.view2 addGestureRecognizer:[self setRecognizer]];
8
Bhavik Rathod

Eh bien, si quelqu'un ne veut pas coder pour l'ajout de la vue des gestes à plusieurs boutons comme kwalker a répondu ci-dessus, et qu'il souhaite le faire via Interface Builder, cela peut vous aider.

1) Vous pouvez ajouter une reconnaissance de geste de presse longue à partir de la bibliothèque d'objets comme vous ajoutez d'autres objets tels que UIButtons et UILabels.

enter image description here Au début, ce que j’ai utilisé est que j’ai pris un seul

2) Définissez les prises de référencement sur UIButton et envoyez les actions avec le propriétaire du fichier.

enter image description here

Remarque: Si vous avez plusieurs objets UIButton ou tout autre objet, vous aurez besoin d'un identificateur de geste distinct pour chacun d'eux. Pour plus de détails, merci de vous référer à cette question . Se tromper de la balise UIButton sur le dispositif de reconnaissance de geste à pression longue

4
rohan-patel

Qu'en est-il de réécrire (recréer) votre geste? Reconnaître chaque fois que vous ajoutez un outil de reconnaissance de gestes pointant vers la même fonction. Dans les cas ci-dessous cela fonctionne. J'utilise IBOutletCollection

Swift 2:

@IBOutlet var topicView: [UIView]!

override func viewDidLoad() {
        for view in self.topicView as [UIView] {
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "viewClicked:"))
    }
}

func viewClicked(recognizer: UITapGestureRecognizer) {
    print("tap")
}
2
febaisi

si vous avez une vue fixe, je vous suggère de faire quelque chose comme ça

[self.view1 addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)]];
[self.view2 addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)]];

de cette façon, réduira plusieurs variables différentes inutiles

2

Remplacer la classe par '<UIScrollViewDelegate> '

Et utilisez cette méthode en classe .m:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}

Cette méthode vous aidera à activer plusieurs balayages sur une seule vue.

2
AnkitRox

Vous pouvez créer une extension générique sur la vue pour ajouter facilement des identificateurs de geste. Ceci est juste un exemple mais il pourrait ressembler à ceci

extension UIView {

    func setGestureRecognizer<Gesture: UIGestureRecognizer>(of type: Gesture.Type, target: Any, actionSelector: Selector, swipeDirection: UISwipeGestureRecognizer.Direction? = nil, numOfTaps: Int = 1) {
    let getRecognizer = type.init(target: target, action: actionSelector)

    switch getRecognizer {
    case let swipeGesture as UISwipeGestureRecognizer:
        guard let direction = swipeDirection else { return }
        swipeGesture.direction = direction
        self.addGestureRecognizer(swipeGesture)
    case let tapGesture as UITapGestureRecognizer:
        tapGesture.numberOfTapsRequired = numOfTaps
        self.addGestureRecognizer(tapGesture)
    default:
        self.addGestureRecognizer(getRecognizer)
    }
  }

}

Pour ajouter un identifiant 2 touches sur une vue, appelez simplement:

let actionSelector = #selector(actionToExecute)
view.setGestureRecognizer(of: UITapGestureRecognizer.self, target: self, actionSelector: actionSelector, numOfTaps: 2)

Vous pouvez également facilement ajouter un identificateur de balayage

view.setGestureRecognizer(of: UISwipeGestureRecognizer.self, target: self, actionSelector: actionSelector, swipeDirection: .down)

etc. Rappelez-vous simplement que la cible doit être liée au sélecteur.

0
Martin