web-dev-qa-db-fra.com

Définition de la direction pour UISwipeGestureRecognizer

Je souhaite ajouter une reconnaissance de geste par balayage simple à mon projet iPhone basé sur les vues. Les gestes dans toutes les directions (droite, bas, gauche, haut) doivent être reconnus.

Il est indiqué dans la documentation pour UISwipeGestureRecognizer:

Vous pouvez spécifier plusieurs directions en spécifiant plusieurs constantes UISwipeGestureRecognizerDirection à l'aide d'opérandes bit-OR. La direction par défaut est UISwipeGestureRecognizerDirectionRight.

Cependant pour moi ça ne marche pas. Lorsque les quatre directions sont activées, seuls les balayages gauche et droit sont reconnus.

- (void)viewDidLoad {
    UISwipeGestureRecognizer *recognizer;

    recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionUp)];
    [[self view] addGestureRecognizer:recognizer];
    [recognizer release]; 
    [super viewDidLoad];
}

-(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
    NSLog(@"Swipe received.");
}

J'ai corrigé le problème en ajoutant quatre identificateurs à la vue, mais je suis curieux de savoir pourquoi cela n'a pas fonctionné comme indiqué dans la documentation.

- (void)viewDidLoad {
    UISwipeGestureRecognizer *recognizer;

    recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
    [[self view] addGestureRecognizer:recognizer];
    [recognizer release];

    recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionUp)];
    [[self view] addGestureRecognizer:recognizer];
    [recognizer release];

    recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionDown)];
    [[self view] addGestureRecognizer:recognizer];
    [recognizer release];

    recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    [recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
    [[self view] addGestureRecognizer:recognizer];
    [recognizer release];

    [super viewDidLoad];
}

-(void)handleSwipeFrom:(UISwipeGestureRecognizer *)recognizer {
    NSLog(@"Swipe received.");
}
131
sandisn

On dirait qu'il y a un bug. Vous pouvez spécifier les directions autorisées comme vous l'avez fait. Mais lorsque vous essayez d'accéder à la direction réelle qui a déclenché le balayage dans la méthode du sélecteur d'action, vous obtenez toujours le masque de bits que vous avez défini à l'origine (pour les directions autorisées).

Cela signifie que les contrôles pour la direction réelle échoueront toujours lorsque plus d'une direction est autorisée. Vous pouvez le voir vous-même assez facilement lorsque vous sortez la valeur de 'direction' dans la méthode du sélecteur (c'est-à-dire -(void)scrollViewSwiped:(UISwipeGestureRecognizer *)recognizer).

Dépôt d'un rapport de bogue (n ° 8276386) auprès d'Apple.

[Mise à jour] J'ai reçu une réponse de Apple) en indiquant que le comportement fonctionne comme prévu.

Ainsi, par exemple, dans une vue de tableau, vous pouvez balayer vers la gauche ou la droite dans une cellule de la vue de tableau pour déclencher la suppression (les directions du geste de balayage seront définies à gauche et à droite).

Cela signifie que la solution de contournement d'origine est la manière dont elle est censée être utilisée. La propriété direction ne peut être utilisée que pour que les gestes soient reconnus correctement, mais pas dans la méthode effectuée sur une reconnaissance réussie pour comparer la direction réelle qui a déclenché la reconnaissance.

114
RupertP

J'ai remarqué que les gestes gauche/droite et haut/bas fonctionnent ensemble par paires. Vous n'avez donc besoin que de spécifier deux identificateurs de geste. Et les docs semblent avoir tort.

25
Lars

Et bien ça craint, j'ai résolu le problème en ajoutant 2 gestes comme Lars l'a mentionné et cela a parfaitement fonctionné ...

1) Gauche/Droite 2) Haut/Bas

  

UISwipeGestureRecognizer *swipeLeftRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
    [swipeLeftRight setDirection:(UISwipeGestureRecognizerDirectionRight | UISwipeGestureRecognizerDirectionLeft )];
    [self.view addGestureRecognizer:swipeLeftRight];

    UISwipeGestureRecognizer *swipeUpDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
    [swipeUpDown setDirection:(UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown )];
    [self.view addGestureRecognizer:swipeUpDown];
22
yunas
UISwipeGestureRecognizer *recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(didSwipe:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[self.view addGestureRecognizer:recognizer];
[recognizer release];

recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(didSwipe:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[self.view addGestureRecognizer:recognizer];
[recognizer release];

Maintenant, c'est la fonction didSwipe

- (void) didSwipe:(UISwipeGestureRecognizer *)recognizer{
      if([recognizer direction] == UISwipeGestureRecognizerDirectionLeft){
          //Swipe from right to left
          //Do your functions here
      }else{
          //Swipe from left to right
          //Do your functions here
      }
 }
13
KarenAnne

Si vous souhaitez qu'il détecte les quatre directions, vous devez créer quatre instances, comme vous l'avez fait dans votre solution de contournement.

Voici pourquoi: La même instance d'UISwipeGestureRecognizer que vous créez est l'instance qui est transmise au sélecteur en tant qu'expéditeur. Donc, si vous le configurez pour reconnaître les quatre directions, il retournera vrai pour sgr.direction == xxx où xxx est l’une des quatre directions.

Voici un solution de rechange qui implique moins de code (suppose l'utilisation d'ARC):

for(int d = UISwipeGestureRecognizerDirectionRight; d <= UISwipeGestureRecognizerDirectionDown; d = d*2) {
    UISwipeGestureRecognizer *sgr = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeFrom:)];
    sgr.direction = d;
    [self.view addGestureRecognizer:sgr];
}
5
tybro0103

Si vous utilisez Xcode 4.2, vous pouvez ajouter des identifiants de geste @ au storyboard, puis lier les identifiants de geste de l'interface graphique à IBActions.

Vous pouvez trouver les reconnaisseurs de geste dans la bibliothèque d'objets du volet Utilitaires (au bas du volet de droite).

Ensuite, c’est juste une question de Ctrl-glisser vers l’action appropriée.

5
Grymm

Voici un exemple de code pour l'utilisation de UISwipeGestureRecognizer. Notez les commentaires.

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    //add gesture recognizer. The 'direction' property of UISwipeGestureRecognizer only sets the allowable directions. It does not return to the user the direction that was actaully swiped. Must set up separate gesture recognizers to handle the specific directions for which I want an outcome.
    UISwipeGestureRecognizer *gestureRight;
    UISwipeGestureRecognizer *gestureLeft;
    gestureRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeRight:)];//direction is set by default.
    gestureLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeLeft:)];//need to set direction.
    [gestureLeft setDirection:(UISwipeGestureRecognizerDirectionLeft)];
    //[gesture setNumberOfTouchesRequired:1];//default is 1
    [[self view] addGestureRecognizer:gestureRight];//this gets things rolling.
    [[self view] addGestureRecognizer:gestureLeft];//this gets things rolling.
}

swipeRight et swipeLeft sont des méthodes que vous utilisez pour effectuer des activités spécifiques en fonction du balayage à gauche ou à droite. Par exemple:

- (void)swipeRight:(UISwipeGestureRecognizer *)gesture
{
    NSLog(@"Right Swipe received.");//Lets you know this method was called by gesture recognizer.
    NSLog(@"Direction is: %i", gesture.direction);//Lets you know the numeric value of the gesture direction for confirmation (1=right).
    //only interested in gesture if gesture state == changed or ended (From Paul Hegarty @ standford U
    if ((gesture.state == UIGestureRecognizerStateChanged) ||
    (gesture.state == UIGestureRecognizerStateEnded)) {

    //do something for a right swipe gesture.
    }
}
2
Greg
UISwipeGestureRecognizer *Updown=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleGestureNext:)];
            Updown.delegate=self;
            [Updown setDirection:UISwipeGestureRecognizerDirectionDown | UISwipeGestureRecognizerDirectionUp];
            [overLayView addGestureRecognizer:Updown];

            UISwipeGestureRecognizer *LeftRight=[[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(handleGestureNext:)];
            LeftRight.delegate=self;
            [LeftRight setDirection:UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight];
            [overLayView addGestureRecognizer:LeftRight];
            overLayView.userInteractionEnabled=NO;


    -(void)handleGestureNext:(UISwipeGestureRecognizer *)recognizer
    {
        NSLog(@"Swipe Recevied");
        //Left
        //Right
        //Top
        //Bottom
    }
2
bhavik

Swift 2.1

Je devais utiliser ce qui suit

    for var x in [
        UISwipeGestureRecognizerDirection.Left,
        UISwipeGestureRecognizerDirection.Right,
        UISwipeGestureRecognizerDirection.Up,
        UISwipeGestureRecognizerDirection.Down
    ] {
        let r = UISwipeGestureRecognizer(target: self, action: "swipe:")
        r.direction = x
        self.view.addGestureRecognizer(r)
    }
2
Andrei

utilisez ceci, cela devrait être l'opération de bit

   gesture.direction & UISwipeGestureRecognizerDirectionUp || 
   gesture.direction & UISwipeGestureRecognizerDirectionDown
1
William Wu

hmm, étrange, ça marche parfaitement pour moi, je fais exactement la même chose

pense que tu devrais essayer regarde

Méthode UIGestureRecognizerDelegate

- (BOOL)gestureRecognizerShouldBegin:(UISwipeGestureRecognizer *)gestureRecognizer {
   // also try to look what's wrong with gesture
   NSLog(@"should began gesture %@", gestureRecognizer);
   return YES;
}

dans les journaux, vous devez voir quelque chose comme:

devrait commencer le geste; target = <(action = actionForUpDownSwipeGestureRecognizer :, target =)>; direction = haut, bas, gauche, droite>

1
iFreeman

Cela me rendait fou. J'ai enfin trouvé un moyen fiable d'avoir plusieurs swipeGestureRecognizers.

Il semble qu'il y ait un bogue dans iOS si le nom de votre sélecteur "action" est le même sur plusieurs swipeGestureRecognizers. Si vous les appelez simplement différemment, par exemple handleLeftSwipeFrom et handleRightSwipeFrom, tout fonctionne.

UISwipeGestureRecognizer *recognizer;

recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleLeftSwipeFrom:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionLeft)];
[[self view] addGestureRecognizer:recognizer];
[recognizer release];

recognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleRightSwipeFrom:)];
[recognizer setDirection:(UISwipeGestureRecognizerDirectionRight)];
[[self view] addGestureRecognizer:recognizer];
[recognizer release];
0
Alex