UITouches потеряны во время мультитач

Мне не удается заставить UIView реагировать на несколько касаний так, как я хочу. В основном некоторые UITouch находятся в UITouchPhaseBegan, но никогда не добираются до UITouchPhaseEnded или UITouchPhaseCancelled. Вот код, который я использую для обработки касаний, который вызывается из touchesBegan:withEvent, touchesMoved:withEvent, touchesEnded:withEvent и touchesCancelled:withEvent. Если я опускаю один палец, затем другой, двигаю ими и одновременно отпускаю, то вывод NSLog иногда Начался! Начал! Завершено! а не Начало! Начал! Закончилось! Завершено!. Эти штрихи куда-то теряются? Как я могу следить за ними?

- (void) handleTouchEvent:(UIEvent *)event {
    for( UITouch* touch in [event allTouches] ) {
        if( touch.phase == UITouchPhaseBegan ) {
            NSLog(@"Began!");
            if( ![m_pCurrentTouches containsObject:touch] )
                [m_pCurrentTouches addObject:touch];
            uint iVoice= [m_pCurrentTouches indexOfObject:touch];
            CGPoint location = [touch locationInView:self];
            m_pTouchPad->SetTouchPoint( location.x, location.y, iVoice );
            m_pTouchPad->SetIsTouching( true, iVoice );
        }
        else if( touch.phase == UITouchPhaseMoved ) {
            uint index= [m_pCurrentTouches indexOfObject:touch];
            CGPoint location = [touch locationInView:self];
            m_pTouchPad->SetTouchPoint( location.x, location.y, index );
        }
        else if( touch.phase == UITouchPhaseEnded || touch.phase == UITouchPhaseCancelled ) {
            uint index= [m_pCurrentTouches indexOfObject:touch];
            [m_pCurrentTouches removeObject:touch];
            NSLog(@"Ended!");
            m_pTouchPad->SetIsTouching( false, index );
        }
    }
}

ИЗМЕНИТЬ:

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

Я придерживаюсь неправильной стратегии для достижения этого?


person Luke    schedule 13.12.2011    source источник
comment
почему вы используете [event allTouches] вместо touches, перешедшего от touchesBegan:withEvent?   -  person Bryan Chen    schedule 10.01.2012


Ответы (2)


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

У Apple есть пример кода, показывающий, как это сделать, поддерживая CFDictionaryRef:

http://developer.apple.com/library/IOs/documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MultitouchEvents/MultitouchEvents.html#//apple_ref/doc/uid/TP40009541-CH3-SW7

(Прокрутите вниз до раздела «Обработка событий мультитач».)

person matt    schedule 10.01.2012

Только что попробовал ваш код, у которого есть некоторые проблемы. Я иногда получаю «Began Began Began End End» для двух пальцев, потому что touchesBegan вызывается два раза, и в первый раз одно начало касания, во второй раз два начала касания.

Я не знаю, почему вы не разделили метод и не поместили код в методы touchesBegan, touchesMoved, touchesEnded. Но вы должны использовать touches, переданный из аргумента, вместо [event allTouches].

- (void) handleTouches:(NSSet *)touches {
    for( UITouch* touch in touches ) {
        if( touch.phase == UITouchPhaseBegan ) {
            NSLog(@"Began!");
        }
        else if( touch.phase == UITouchPhaseMoved ) {

        }
        else if( touch.phase == UITouchPhaseEnded || touch.phase == UITouchPhaseCancelled ) {
            NSLog(@"Ended!");
        }
    }
}

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

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

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

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
    [self handleTouches:touches];
}
person Bryan Chen    schedule 10.01.2012
comment
Я использовал что-то подобное при перемещении представления. Это прекрасно работает. - person Dylan Gattey; 10.01.2012