Направление настройки для UISwipeGestureRecognizer

Я хочу добавить простое распознавание жестов в мой проект на основе iPhone. Следует признать жесты во всех направлениях (справа, вниз, влево, вверх).

В документах для UISwipeGestureRecognizer указано:

Вы можете указать несколько направлений, указав несколько констант UISwipeGestureRecognizerDirection с помощью операндов поразрядного ИЛИ. По умолчанию используется UISwipeGestureRecognizerDirectionRight.

Однако для меня это не работает. Когда все четыре направления обозначены OR, распознаются только левые и правые штрихи.

- (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.");
}

Я исправил это, добавив четыре представления в представление, но мне любопытно узнать, почему он не работал, как рекламируется в документах?

- (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.");
}

Ответ 1

Кажется, что есть ошибка. Вы можете указать разрешенные направления (ы), как и вы. Но когда вы пытаетесь получить доступ к фактическому направлению, вызвавшему салфетки в методе селектора действий, вы все равно получаете установленную вами битовую маску (для разрешенных направлений).

Это означает, что проверки фактического направления всегда будут терпеть неудачу, если разрешено более одного направления. Вы можете увидеть это для себя довольно легко, когда вы выводите значение "direction" в методе селектора (т.е. -(void)scrollViewSwiped:(UISwipeGestureRecognizer *)recognizer).

Подал сообщение об ошибке (# 8276386) в Apple.

[Update] Я получил ответ от Apple, говоря, что поведение работает так, как предполагалось.

Так, например, в представлении таблицы вы можете прокручивать влево или вправо в ячейке таблицы, чтобы вызвать "delete" (это приведет к тому, что указатели салфетки будут установлены слева и справа).

Это означает, что первоначальное обходное решение - это способ, которым он должен использоваться. Свойство direction можно использовать только для правильного распознавания жестов, но не в методе, выполняемом при успешном распознавании, для сравнения фактического направления, вызвавшего распознавание.

Ответ 2

Я заметил, что жесты влево/вправо и вверх/вниз работают вместе парами, поэтому вам нужно всего лишь указать два распознавателя жестов. И документы действительно кажутся неправильными.

Ответ 3

Хорошо, что это отстой, я решил проблему, добавив 2 жестов, как упоминал Ларс, и это отлично сработало...

1) Влево/Вправо 2) Вверх/Вниз

  

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];

Ответ 4

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];

Теперь это функция 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
      }
 }

Ответ 5

Если вы используете Xcode 4.2, вы можете добавить Grecure Recognizers @раскадровки, а затем связать GUI Gesture Recognizers с IBActions.

Вы можете найти Распознавания жестов в библиотеке объектов в области утилиты (внизу правой панели).

Тогда это просто вопрос перетаскивания управления в соответствующее действие.

Ответ 6

Если вы хотите, чтобы он обнаружил все четыре направления, вам нужно создать четыре экземпляра, как это было в вашей работе.

Здесь Почему: Тот же экземпляр создаваемого вами UISwipeGestureRecognizer - это экземпляр, который передается селектору в качестве отправителя. Поэтому, если вы установите его для распознавания всех четырех направлений, он вернет true для sgr.direction == xxx, где xxx - любое из четырех направлений.

Здесь альтернативная работа, которая включает меньше кода (предполагает использование 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];
}

Ответ 7

Вот пример кода для использования UISwipeGestureRecognizer. Заметьте комментарии.

- (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 и swipeLeft - это методы, которые вы используете для выполнения определенных действий, основанных на прокрутке влево или вправо. Например:

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

Ответ 8

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
    }

Ответ 9

Swift 2.1

Мне пришлось использовать следующие

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

Ответ 10

Хмм, странно, он отлично работает для меня, я делаю то же самое

Думаю, вам стоит попробовать посмотреть

Метод UIGestureRecognizerDelegate

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

в журналах вы должны увидеть что-то вроде:

должен был начать жест; target = < (action = actionForUpDownSwipeGestureRecognizer:, target =) > ; направление = вверх, вниз, влево, вправо >

Ответ 11

используйте это, это должна быть операция бит

   gesture.direction & UISwipeGestureRecognizerDirectionUp || 
   gesture.direction & UISwipeGestureRecognizerDirectionDown

Ответ 12

Это сводило меня с ума. Я, наконец, понял надежный способ иметь несколько swipeGestureRecognizers.

Похоже, что в iOS есть ошибка, если имя вашего селектора "действия" одинаково для нескольких swipeGestureRecognizers. Если вы просто называете их по-другому, например. handleLeftSwipeFrom и handleRightSwipeFrom, все работает.

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];