質問

I'm having trouble getting a UIView to respond how I want with multiple touches. Basically certain UITouches are in UITouchPhaseBegan but never make it to UITouchPhaseEnded or UITouchPhaseCancelled. Here's the code I'm using to handle touches, which is called from touchesBegan:withEvent, touchesMoved:withEvent, touchesEnded:withEvent and touchesCancelled:withEvent. If I put one finger down, then another, move them, and release them simultaneously, the NSLog output is sometimes Began! Began! Ended! rather than Began! Began! Ended! Ended!. Are these touches getting lost somewhere? How can I keep track of them?

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

EDIT:

I'm offering a bounty because I really want a good solution to this. To summarize: I need a system where every touch that begins also ends, so if a user puts down one finger and then another elsewhere, I can see both touches begin, and by the time there are no fingers in contact with the device anymore, I have seen both touches end.

Am I pursuing the wrong strategy to achieve this?

役に立ちましたか?

解決

One event can report many touches. So you are sometimes getting "Ended!" once, because only one event arrived and only one touch event handler call was made - but it reported both touches ending. If you are manually handling multiple simultaneous touches (fingers), it is up to you to track each touch individually and check every touch in every event to see how many of your touches are being reported and decide what to do.

Apple has sample code showing how to do this by maintaining a CFDictionaryRef:

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

(Scroll down to the section called "Handling Multitouch Events".)

他のヒント

Just tried your code, which have some problems. I get "Began Began Began End End" for two fingers sometimes because touchesBegan get called two times and first time have one began touch second time have two began touches.

I don't know why you didn't split the method and put the code into the touchesBegan, touchesMoved, touchesEnded methods. But you should use touches that passed from the argument instead of [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];
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top