iOS теряет касания? - PullRequest
       8

iOS теряет касания?

8 голосов
/ 17 февраля 2012

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

Пример кода:

int touchesStarted = 0;
int touchesFinished = 0;

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    touchesStarted += touches.count;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    touchesFinished += touches.count;
    NSLog(@"%d / %d", touchesStarted, touchesFinished);
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self touchesEnded:touches withEvent:event];
}

Ответы [ 3 ]

5 голосов
/ 17 февраля 2012

Не забудьте о touchesCancelled: Ссылка на UIResponder

Редактирование в ответ на обновление автора:

Каждый сенсорный объект указывает, в какой фазе он находится:

typedef enum {
    UITouchPhaseBegan,
    UITouchPhaseMoved,
    UITouchPhaseStationary,
    UITouchPhaseEnded,
    UITouchPhaseCancelled,
} UITouchPhase;

Я считаю, что если касание начинается и заканчивается в том же наборе событий касания, -touchesBegan:withEvent: будет называться , но будет содержать касания, которые закончились или были отменены .

Затем вы должны изменить свой счетный код, чтобы он выглядел следующим образом:

int touchesStarted = 0;
int touchesFinished = 0;

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self customTouchHandler:touches];
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self customTouchHandler:touches];
}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
{
    [self customTouchHandler:touches];
}
- (void)customTouchHandler:(NSSet *)touches
{
    for(UITouch* touch in touches){
        if(touch.phase == UITouchPhaseBegan)
            touchesStarted++;
        if(touch.phase == UITouchPhaseEnded || touch.phase == UITouchPhaseCancelled)
            touchesFinished++;
    }
    NSLog(@"%d / %d", touchesStarted, touchesFinished);
}

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

3 голосов
/ 20 апреля 2012

Одна вещь, которую нужно запомнить ... Вы можете получить несколько касаний, которые имеют несколько нажатий. Не забудьте учесть tapCount.

Однако, если у вас все еще есть проблема, вы можете рассмотреть все прикосновения к событию, хотя оно представляет некоторые другие проблемы управления ...

HACK ALERT

Я кодировал следующее HACK , чтобы обойти это. Иногда touchesEnded не вызывается, НО, касания появляются как часть всех касаний в событии.

Обратите внимание, что теперь вы можете обрабатывать одно и то же "отмененное" или "законченное" касание несколько раз. Если это проблема, вы должны сохранить собственное состояние «ожидающих» касаний и удалить их, когда закончите.

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

- (void) touchesEndedOrCancelled:(NSSet *)touches
{
    __block NSMutableSet *ended = nil;
    __block NSMutableSet *canceled = nil;
    [touches enumerateObjectsUsingBlock:^(UITouch *touch, BOOL *stop) {
        if (touch.phase == UITouchPhaseEnded) {
            if (!ended) ended = [NSSet setWithObject:touch];
            else [ended addObject:touch];
        } else if (touch.phase == UITouchPhaseCancelled) {
            if (!canceled) canceled = [NSSet setWithObject:touch];
            else [canceled addObject:touch];
        }
    }];
    if (ended) [self touchesEnded:ended withEvent:nil];
    if (canceled) [self touchesCancelled:canceled withEvent:nil];
}

Затем вызовите его в конце касания Начал и коснулся Перемещено ...

[self touchesEndedOrCancelled:event.allTouches];

Чтобы это работало, touchesEnded / Cancelled не должно подавляться нулевым событием. Кроме того, «другое» должно быть обработано. В касаниях закругленный ...

[self touchesCancelled:[event.allTouches objectsPassingTest:^BOOL(UITouch *touch, BOOL *stop) {
    return touch.phase == UITouchPhaseCancelled;
}] withEvent:nil];

и в касаниях Отменено ...

[self touchesEnded:[event.allTouches objectsPassingTest:^BOOL(UITouch *touch, BOOL *stop) {
    return touch.phase == UITouchPhaseEnded;
}] withEvent:nil];
0 голосов
/ 26 апреля 2012

Возможно, вам потребуется предоставить более подробную информацию, но ....

Если вы проведете пальцем по краю экрана, это событие покажет, что касание запущено, а касание перемещено, но конца нет, поскольку на самом деле это не так.конец (поднять палец).Это может быть вашей проблемой, что событие не произошло.Кроме того, существует ограничение на количество касаний в режиме мультитач, если вы нажимаете, скажем, 10 раз, а затем до системы, чтобы определить, какие события на самом деле, а какие ложные, кажется, что вы используете оборудование неправильно.

...