Распознаватель жестов перестал работать в iOS 4.3 - PullRequest
3 голосов
/ 14 марта 2011

Мой код распознавания жестов работал нормально в iOS 4.2, но в iOS 4.3 он не работает. Я не могу найти никаких документированных изменений в средствах распознавания жестов с iOS 4.2 до 4.3, но на iPad и в симуляторе я подтвердил, что мой код больше не работает.

Вот что я делаю:

В методе ViewDidLoad контроллера моего представления я поставил:

UISwipeGestureRecognizer *swipeUpGesture = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipedScreenLeft:)] autorelease];
swipeUpGesture.numberOfTouchesRequired = 2;
swipeUpGesture.direction = (UISwipeGestureRecognizerDirectionLeft);
[scrollView addGestureRecognizer:swipeUpGesture];

В iOS 4.2 это работает как положено, но в iOS 4.3 swipedScreenLeft никогда не вызывается, даже когда я провожу двумя пальцами. Все компилируется и работает без ошибок и предупреждений.

Есть ли что-нибудь, что могло бы помешать этому распознавателю жестов работать в iOS 4.3, даже если он отлично работает в iOS 4.2?

Также я заметил, что под iOS 4.2, если я коснулся экрана двумя пальцами, но не сделал правильный жест, ничего бы не случилось, но в iOS 4.3, если я коснусь экрана двумя пальцами, это действует так, как будто я только касаясь одним пальцем. Как будто iOS 4.3 не распознает события мультитач в моем приложении.

Еще одно замечание: мой tapGestureRecognizer отлично работает в iOS 4.3, это просто swipeGestureRecognizer, который не работает.

Ответы [ 3 ]

8 голосов
/ 15 марта 2011

Проблема только с UIScrollView, я также пришел в ярость: http://i.stack.imgur.com/dqx3d.png

[ОБНОВЛЕНИЕ 1] Здесь решение:

Ситуация: представление UIViewController имеет UIScrollViewв качестве подпредставления (подкачка просмотра с прокруткой отключена).

Код, который я использую для добавления жеста к UIView:

UISwipeGestureRecognizer *swipeLeftRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipedScreenLeft:)];
[swipeLeftRecognizer setNumberOfTouchesRequired:2.0f];
swipeLeftRecognizer.delegate = self;
[swipeLeftRecognizer setDirection:UISwipeGestureRecognizerDirectionLeft];

[self.view addGestureRecognizer:swipeLeftRecognizer];

[swipeLeftRecognizer release];

Чтобы быть включенной в iOS 4.3, мне нужно было только добавить UIViewControllerкак UIGestureRecognizerDelegate

Затем я использовал следующий метод делегата, чтобы перехватить и разрешить одновременное распознавание panGesture в scrollView с использованием вида swipe.Вот код:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{

    if ([gestureRecognizer isKindOfClass:[UISwipeGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
        return YES;
    }

    return NO;

}

[ОБНОВЛЕНИЕ 2]

Чтобы отключить панорамирование UIScrollView двумя пальцами, я ДУМАЮ, что вам нужно сделать свой scrollview, пользовательский подкласс класса UISCrollView иизменить поведение детектора panGesture, НО я не пытался это сделать.Вместо этого я выбрал более ленивое решение, в основном я включаю / отключаю функцию прокрутки scrollView на основе текущего состояния UISwipeGestureRecognizer.Более того, чтобы предотвратить двойное касание в другом направлении, я специально для этой цели подключил другой распознаватель.

Вам необходимо создать два свойства для ваших детекторов прокрутки.

@property (nonatomic,assign) UISwipeGestureRecognizer *swipeRightRecognizer;
@property (nonatomic,assign) UISwipeGestureRecognizer *swipeLeftRecognizer;

Затем я запрограммировал это так:

[self setSwipeRightRecognizer:[[UISwipeGestureRecognizer alloc] initWithTarget:nil action:nil]];
[swipeRightRecognizer setNumberOfTouchesRequired:2.0f];
swipeRightRecognizer.delegate = self;
[swipeRightRecognizer setDirection:UISwipeGestureRecognizerDirectionRight];
[self addObserver:self forKeyPath:@"swipeRightRecognizer.state" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:NULL];
[self.view addGestureRecognizer:swipeRightRecognizer];
[swipeRightRecognizer release];

[self setSwipeLeftRecognizer:[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipedScreenLeft:)]];
[swipeLeftRecognizer setNumberOfTouchesRequired:2.0f];
swipeLeftRecognizer.delegate = self;
[swipeLeftRecognizer setDirection:UISwipeGestureRecognizerDirectionLeft];
[self addObserver:self forKeyPath:@"swipeLeftRecognizer.state" options:(NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld) context:NULL];
[self.view addGestureRecognizer:swipeLeftRecognizer];
[swipeLeftRecognizer release];

, затем добавьте этот метод:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {

    if (self.swipeRightRecognizer.state == UIGestureRecognizerStateFailed) {
        self.scrollView.scrollEnabled = YES;
        return;
    }

    if ([self.swipeRightRecognizer numberOfTouches] != 2.0f) {
        self.scrollView.scrollEnabled = YES;   
    }
    else{
        self.scrollView.scrollEnabled = NO;   
    }
}

И обновите существующий метод, который я опубликовал в предыдущем «[ОБНОВЛЕНО]»:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{

    if ([gestureRecognizer isKindOfClass:[UISwipeGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
        if ([gestureRecognizer numberOfTouches] != 2.0f) {
            self.scrollView.scrollEnabled = YES;   
        }
        else{
            self.scrollView.scrollEnabled = NO;   
        }

        return YES;
    }
    return NO;
}

Наконец, удалите наблюдателей из сделки:

[self removeObserver:self forKeyPath:@"swipeRightRecognizer.state"];
[self removeObserver:self forKeyPath:@"swipeLeftRecognizer.state"];

Могу поспорить, что есть более чистое решение, но оно работает ...

Надеюсь, это поможет;)

1 голос
/ 19 мая 2012

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

0 голосов
/ 14 марта 2011

Возможно, мой код поможет вам решить вашу проблему.Я тестировал код на iPad с iOS 4.3, и он отлично работает

UISwipeGestureRecognizer *oSwipeLeft = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(mPreviousPage:) ] autorelease];
oSwipeLeft.numberOfTouchesRequired = 2;
oSwipeLeft.direction = UISwipeGestureRecognizerDirectionLeft;
[self.view addGestureRecognizer:oSwipeLeft];

UISwipeGestureRecognizer *oSwipeRight = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(mNextPage:) ] autorelease];
oSwipeRight.numberOfTouchesRequired = 2;
oSwipeRight.direction = UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:oSwipeRight];

UISwipeGestureRecognizer *oSwipeUp = [[[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(mPreviousPage:) ] autorelease];
oSwipeUp.numberOfTouchesRequired = 2;
oSwipeUp.direction = UISwipeGestureRecognizerDirectionUp;
[self.view addGestureRecognizer:oSwipeUp];
...