Comment reconnaître swipe dans les 4 directions?

j'ai besoin de reconnaître glisse dans toutes les directions ( Haut/Bas/Gauche/Droite ). Pas simultanément, mais je dois les reconnaître.

j'ai essayé:

  UISwipeGestureRecognizer *Swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(SwipeRecognizer:)];
  Swipe.direction = (UISwipeGestureRecognizerDirectionLeft | 
                     UISwipeGestureRecognizerDirectionRight |
                     UISwipeGestureRecognizerDirectionDown | 
                     UISwipeGestureRecognizerDirectionUp);
  [self.view addGestureRecognizer:Swipe];
  [Swipe release];

mais rien n'est apparu sur SwipeRecognizer

voici le code pour SwipeRecognizer:

- (void) SwipeRecognizer:(UISwipeGestureRecognizer *)sender {
  if ( sender.direction == UISwipeGestureRecognizerDirectionLeft )
    NSLog(@" *** SWIPE LEFT ***");
  if ( sender.direction == UISwipeGestureRecognizerDirectionRight )
    NSLog(@" *** SWIPE RIGHT ***");
  if ( sender.direction == UISwipeGestureRecognizerDirectionDown )
    NSLog(@" *** SWIPE DOWN ***");
  if ( sender.direction == UISwipeGestureRecognizerDirectionUp )
    NSLog(@" *** SWIPE UP ***");
}

Comment faire? Comment affecter à mon objet Swipe toutes les directions différentes?

25
demandé sur pasawaya 2011-11-18 15:35:08

8 réponses

vous mettez la direction comme ceci

  UISwipeGestureRecognizer *Swipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(SwipeRecognizer:)];
  Swipe.direction = (UISwipeGestureRecognizerDirectionLeft | 
                     UISwipeGestureRecognizerDirectionRight |
                     UISwipeGestureRecognizerDirectionDown | 
                     UISwipeGestureRecognizerDirectionUp);

C'est ce que sera la direction quand vous recevrez le rappel, donc il est normal que tous vos tests échouent. Si vous aviez

- (void) SwipeRecognizer:(UISwipeGestureRecognizer *)sender {
  if ( sender.direction | UISwipeGestureRecognizerDirectionLeft )
    NSLog(@" *** SWIPE LEFT ***");
  if ( sender.direction | UISwipeGestureRecognizerDirectionRight )
    NSLog(@" *** SWIPE RIGHT ***");
  if ( sender.direction | UISwipeGestureRecognizerDirectionDown )
    NSLog(@" *** SWIPE DOWN ***");
  if ( sender.direction | UISwipeGestureRecognizerDirectionUp )
    NSLog(@" *** SWIPE UP ***");
}

les tests réussiraient (mais tous réussiraient pour que vous n'obteniez aucune information d'eux). Si vous voulez distinguer entre des glissières dans des directions différentes, vous aurez besoin de reconnaissances de geste séparées.


EDIT

comme indiqué dans les commentaires, Voir cette réponse . Apparemment, même cela ne fonctionne pas. Vous devez créer balayez avec une seule direction pour rendre votre vie plus facile.

21
répondu jbat100 2017-05-23 11:46:37

malheureusement, vous ne pouvez pas utiliser la propriété direction pour écouter le reconnaisseur; elle vous donne seulement les directions détectées par le reconnaisseur. J'ai utilisé deux UISwipeGestureRecognizer différents à cette fin, voir ma réponse ici: https://stackoverflow.com/a/16810160/936957

4
répondu Yunus Nedim Mehel 2017-05-23 12:32:21

j'ai déjà rencontré ce problème. Ce que j'ai fini par faire était de créer une sous-classe D'UIView, d'écraser touchesMoved: et de faire quelques calculs pour calculer la direction.

Voici l'idée générale:

#import "OmnidirectionalControl.h"

typedef NS_ENUM(NSInteger, direction) {
    Down = 0, DownRight = 1,
    Right = 2, UpRight = 3,
    Up = 4, UpLeft = 5,
    Left = 6, DownLeft = 7
};

@interface OmnidirectionalControl ()

@property (nonatomic) CGPoint startTouch;
@property (nonatomic) CGPoint endTouch;

@end

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    self.startTouch = [[touches allObjects][0] locationInView:self];
}

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
    self.lastTouch = [[[touches allObjects] lastObject] locationInView:self];
    NSLog(@"Direction: %d", [self calculateDirectionFromTouches]);
}

-(direction)calculateDirectionFromTouches {
    NSInteger xDisplacement = self.lastTouch.x-self.startTouch.x;
    NSInteger yDisplacement = self.lastTouch.y-self.startTouch.y;

    float angle = atan2(xDisplacement, yDisplacement);
    int octant = (int)(round(8 * angle / (2 * M_PI) + 8)) % 8;

    return (direction) octant;
}

par souci de simplicité dans touchesMoved: , Je n'enregistre que la direction, mais vous pouvez faire ce que vous voulez avec cette information (par exemple, la passer à un délégué, poster une notification avec elle, etc.). Dans touchesMoved vous aurez également besoin une méthode pour reconnaître si le balayage est terminé ou non, mais ce n'est pas tout à fait pertinent à la question donc je vais vous laisser. Le calcul dans calculateDirectionFromTouches est expliqué ici .

4
répondu pasawaya 2017-04-13 12:18:41

j'ai finalement trouvé la réponse la plus simple, s'il vous plaît noter ceci comme la réponse si vous êtes d'accord.

si vous n'avez qu'un seul swipe de direction + pan, vous dites juste: [myPanRecogznier requirgesturerecognizertofail:mySwipeRecognizer];

mais si vous avez deux ou plusieurs swipes, vous ne pouvez pas passer un tableau dans cette méthode. Pour cela, il ya UIGestureRecognizerDelegate que vous devez mettre en œuvre.

Par exemple, si vous voulez reconnaissez 2 swipes (à gauche et à droite) et vous voulez aussi permettre à l'utilisateur de pointer du doigt, vous définissez les reconnaisseurs de geste comme des propriétés ou des variables d'instance, et ensuite vous définissez votre VC comme le délégué sur le reconnaisseur de geste de pan:

_swipeLeft = [[UISwipeGestureRecognizer alloc] ...]; // use proper init here
_swipeRight = [[UISwipeGestureRecognizer alloc] ...]; // user proper init here
_swipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
_swipeRight.direction = UISwipeGestureRecognizerDirectionRight;
_pan = [[UIPanGestureRecognizer alloc] ...]; // use proper init here

_pan.delegate = self;

// then add recognizers to your view

vous mettez alors en œuvre - (BOOL)gestureRecognizer: (UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer: (UIGestureRecognizer *)otherGestureRecognizer delegate method, like so:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    if (gestureRecognizer == _pan && (otherGestureRecognizer == _swipeLeft || otherGestureRecognizer == _swipeRight)) {
        return YES;
    }

    return NO;
}

cela indique à la pan gestuelle reconnaître de ne travailler que si les deux glissières gauche et droite ne sont pas reconnus - parfait!

avec un peu de chance dans le futur Apple nous laissera juste passer un tableau à la méthode requesgesturerecognizertofail:.

2
répondu Alex the Ukrainian 2013-12-22 21:41:11

vous pouvez ajouter seulement une diagonale par SwipeGesture, alors...

    UISwipeGestureRecognizer *swipeV = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(action)];
    UISwipeGestureRecognizer *swipeH = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(action)];
    swipeH.direction = ( UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight  );
    swipeV.direction = ( UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown );
    [self addGestureRecognizer:swipeH];
    [self addGestureRecognizer:swipeV];
     self.userInteractionEnabled = YES;
1
répondu Damien Romito 2014-06-04 23:13:52

utilisez un UIPanGestureRecogizer et de détecter les directions de balayage que vous vous souciez. consultez la documentation UIPanGestureRecognizer pour plus de détails. -rrh

// add pan recognizer to the view when initialized
UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panRecognized:)];
[panRecognizer setDelegate:self];
[self addGestureRecognizer:panRecognizer]; // add to the view you want to detect swipe on


-(void)panRecognized:(UIPanGestureRecognizer *)sender
{
    if (sender.state == UIGestureRecognizerStateBegan) {
        // you might want to do something at the start of the pan
    }

    CGPoint distance = [sender translationInView:self]; // get distance of pan/swipe in the view in which the gesture recognizer was added
    CGPoint velocity = [sender velocityInView:self]; // get velocity of pan/swipe in the view in which the gesture recognizer was added
    float usersSwipeSpeed = abs(velocity.x); // use this if you need to move an object at a speed that matches the users swipe speed
    NSLog(@"swipe speed:%f", usersSwipeSpeed);
    if (sender.state == UIGestureRecognizerStateEnded) {
        [sender cancelsTouchesInView]; // you may or may not need this - check documentation if unsure
        if (distance.x > 0) { // right
            NSLog(@"user swiped right");
        } else if (distance.x < 0) { //left
            NSLog(@"user swiped left");
        }
        if (distance.y > 0) { // down
            NSLog(@"user swiped down");
        } else if (distance.y < 0) { //up
            NSLog(@"user swiped up");
        }
        // Note: if you don't want both axis directions to be triggered (i.e. up and right) you can add a tolerence instead of checking the distance against 0 you could check for greater and less than 50 or 100, etc.
    }
}

CHANHE IN STATEEND CODE WITH THIS

/ / if YOU WANT ONLY SINGLE SWIPE FROM UP,DOWN, LEFT AND RIGHT

if (sender.state == UIGestureRecognizerStateEnded) {
        [sender cancelsTouchesInView]; // you may or may not need this - check documentation if unsure
        if (distance.x > 0 && abs(distance.x)>abs(distance.y)) { // right
            NSLog(@"user swiped right");
        } else if (distance.x < 0 && abs(distance.x)>abs(distance.y)) { //left
            NSLog(@"user swiped left");
        }
        if (distance.y > 0 && abs(distance.y)>abs(distance.x)) { // down
            NSLog(@"user swiped down");
        } else if (distance.y < 0 && abs(distance.y)>abs(distance.x)) { //up
            NSLog(@"user swiped up");
        }

    } 
0
répondu Richie Hyatt 2013-11-13 04:51:35
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");
}
0
répondu bhavik 2014-09-22 12:00:19

il pourrait ne pas être la meilleure solution, mais vous pouvez toujours spécifier différent UISwipeGestureRecognizer pour chaque direction de balayage que vous voulez détecter.

dans la méthode viewDidLoad il suffit de définir le UISwipeGestureRecognizer requis:

- (void)viewDidLoad{
    UISwipeGestureRecognizer *recognizerUp = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeUp:)];
    recognizerUp.direction = UISwipeGestureRecognizerDirectionUp;
    [[self view] addGestureRecognizer:recognizerUp];

    UISwipeGestureRecognizer *recognizerDown = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeDown:)];
    recognizerDown.direction =  UISwipeGestureRecognizerDirectionDown;
    [[self view] addGestureRecognizer:recognizerDown];
}

alors il suffit de mettre en œuvre les méthodes respectives pour manipuler les glissières:

- (void)handleSwipeUp:(UISwipeGestureRecognizer *)sender{
    if (sender.state == UIGestureRecognizerStateEnded){
        NSLog(@"SWIPE UP");
    }
}


- (void)handleSwipeDown:(UISwipeGestureRecognizer *)sender{
    if (sender.state == UIGestureRecognizerStateEnded){
        NSLog(@"SWIPE DOWN");
    }
}
0
répondu Daniel Belém Duarte 2015-06-13 19:45:21