Встановлення напрямку для UISwipeGestureRecognizer


132

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

Це зазначено в документах для UISwipeGestureRecognizer:

Ви можете вказати кілька напрямків, вказавши кілька констант UISwipeGestureRecognizerDirection, використовуючи побітові або АБО операнди. Напрямок за замовчуванням - UISwipeGestureRecognizerDirectionRight.

Однак для мене це не працює. Коли всі чотири напрямки OR'ed, розпізнаються лише лівий і правий пальці.

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

3
це абсолютно не пов'язано, але [super viewDidLoad]; має бути першим висловом у - (недійсним) viewDidLoad
Mehta

Відповіді:


115

Схоже, є помилка. Ви можете вказати дозволені напрямки, як ви робили. Але коли ви намагаєтеся отримати доступ до фактичного напрямку, який викликав проведенне пальцем у методі вибору дії, ви все одно отримаєте бітну маску, яку ви встановили спочатку (для дозволених напрямків).

Це означає, що перевірка справжнього напрямку завжди буде невдалою, якщо дозволено більше 1 напрямку. Ви можете переконатися в цьому досить легко, коли виводите значення "напрям" у методі селектора (тобто -(void)scrollViewSwiped:(UISwipeGestureRecognizer *)recognizer).

Подав звіт про помилку (# 8276386) в Apple.

[Оновлення] Я отримав відповідь від Apple, що поведінка працює так, як було призначено.

Так, наприклад, у поданні таблиці ви можете провести пальцем ліворуч або праворуч у комірці подання таблиці, щоб викликати "видалити" (це матиме вказівки руху пальцем пальцем ліворуч та праворуч)

Це означає, що оригінальне рішення - це спосіб, яким його слід використовувати. Властивість напряму може використовуватися лише для правильного розпізнавання жестів, але не в методі, виконаному на успішному розпізнаванні, для порівняння фактичного напрямку, який ініціював розпізнавання.


35
Я готовий зробити ставку на те, що майже кожен, хто вперше використовує розпізнавальник жестів пальцями, робить таке саме неправильне припущення про те, як має діяти властивість напряму.
пам’ятки

Нерозумно створити 4 різних розпізнавача, щоб відслідковувати пальці вгору, вниз, вліво та вправо, але ви є.
пам’ятки

Уау, що це щось смокче, не величезна угода, але здається, щось, що вони могли б додати
marchinram

2
Їх заголовок містить: @property (неатомічний) UISwipeGestureRecognizerDirection напрямок; // за замовчуванням - UISwipeGestureRecognizerDirectionRight. потрібний напрямок пальця. може бути вказано кілька напрямків
nicktmro

1
Погодились, що це здається дивним втіленням з боку Apple. Ви повинні мати змогу вказати кілька напрямків, а потім протестувати один із цих напрямків.
ChrisP

25

Я помітив, що жести вліво / вправо та вгору / вниз працюють разом у парах, тому вам потрібно вказати лише два розпізнавача жестів. І документи, здається, помиляються.


Це правильне рішення. 2 ГР, по одному вгору і вниз / по одному вліво і вправо. Бінго!
logancautrell

22

Ну, це гарно, я вирішив проблему, додавши два жести, як згадував Ларс, і це спрацювало чудово ...

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

13
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, ви можете додати інструменти розпізнавання жестів @ дошка розмов, а потім зв’язати розпізнавачі жестів GUI з IBActions.

Ви можете знайти розпізнавачі жестів у бібліотеці об'єктів на панелі утиліт (у нижній частині правої області).

Тоді це лише питання контролю-перетягування до відповідних дій.


5

Якщо ви хочете, щоб він виявив усі чотири напрямки, вам потрібно створити чотири екземпляри, як це було зроблено у вашій роботі.

Ось чому : Той самий екземпляр UISwipeGestureRecognizer, який ви створюєте, - це екземпляр, який передається селектору як відправник. Отже, якщо встановити його для розпізнавання всіх чотирьох напрямків, воно повернеться істинним, 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];
}

2

Ось зразок коду для використання 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.
    }
}

2
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

Швидкий 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)
    }

1

хм, дивно, це працює ідеально для мене, я роблю точно те саме

думаю, вам варто спробувати подивитися

Метод UIGestureRecognizerDelegate

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

у журналах ви повинні побачити щось на кшталт:

слід почати жестом; target = <(action = actionForUpDownSwipeGestureRecognizer :, target =)>; напрям = вгору, вниз, вліво, вправо>


Що не працює? gestureRecognizerShouldBegin: прекрасно працює.
Данял Айтекін

1

використовувати це, це повинна бути бітова операція

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

0

Це зводило мене з розуму. Нарешті я з’ясував надійний спосіб отримати декілька swipeGestureRecognizers.

Виявляється, в iOS є помилка, якщо назва вашого селектора "action" однакове для кількох 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];
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.