[iPhone]處理多點觸控

UIView 繼承的 UIResponder (負責UI事件處理) 類中提供了四個方法處理多點觸控: spa

-  ( void )touchesBegan : (NSSet  * )touches withEvent : (UIEvent  * )event ;
-  ( void )touchesMoved : (NSSet  * )touches withEvent : (UIEvent  * )event ;
-  ( void )touchesEnded : (NSSet  * )touches withEvent : (UIEvent  * )event ;
-  ( void )touchesCancelled : (NSSet  * )touches withEvent : (UIEvent  * )event ;

touchesBegan方法在觸控開始時被調用,
touchesMoved方法在觸控移動時被調用
touchesEnded方法在觸控結束時被調用
touchesCancelled方法在系統強制結束觸控時被調用 對象

上述方法的參數: 繼承

  1. event 爲觸控動做引起的UI事件,只有發生了UI事件UIResponder的相應處理方法纔會被調用。傳遞給上述方法的UI事件都是「touch」類型的,它關聯了一系列UITouch對象來表明發生該事件時全部處於各類狀態(began, moved, ended, cancelled )下的觸控動做。
  2. touches 一樣是一系列 UITouch 對象的集合(NSSet),不過它只包含處於特定狀態的觸控動做。比方說調用touchesBegan 時傳遞的就是全部處在 began 狀態(phase)的UITouch對象。

相關類型說明: 接口

  • UIEvent 對象表明了 iPhone OS 中一個UI事件,主要有三種類型:touch,motion,remote control。
  • UITouch對象表明一根手指在某一個UI事件發生時刻的動做,它有四種狀態(phase),began, moved, ended, cancelled。
  • 觸控動做會引起 touch 類的UI事件,而這個UI事件中也就包括了一系列 UITouch 對象來記錄當時的全部手指的動做。當 touch 類型的UI事件發生的時候會被交給 UIResponder 處理,繼而調用上述四個方法。

OpenGL ES 程序模板中的多點觸控處理 事件

  • OES 程序模板中的類繼承關係爲 EAGLView :UIView :UIResponder
  • 在 EAGLView 類中實現了上述四個方法,並分別在其中用不一樣的標籤調用 ESRenderer 的 view 方法。
  • ESRenderer 協議(就是接口)中提供了四個同名同參的 view 方法,用標籤來區分調用:
    @optional
    -  ( void )view : (UIView * )view touchesBegan : (NSSet * )touches withEvent : (UIEvent * )event ;
    -  ( void )view : (UIView * )view touchesMoved : (NSSet * )touches withEvent : (UIEvent * )event ;
    -  ( void )view : (UIView * )view touchesEnded : (NSSet * )touches withEvent : (UIEvent * )event ;
    -  ( void )view : (UIView * )view touchesCancelled : (NSSet * )touches withEvent : (UIEvent * )event ;
  • 實現了ESRenderer接口的 ES1Renderer 和 ES2Renderer 最終在 View 方法中負責觸控事件的處理。

獲取各類觸控信息的方法
獲取觸控對象(UITouch) ci

  • 經過 event 參數獲取 UITouch 集合
    //全部關聯的UITouch
    -  (NSSet  * )allTouches ;
    //指定窗口的UITouch
    -  (NSSet  * )touchesForWindow : (UIWindow  * )window ;
    //指定View上的UITouch
    -  (NSSet  * )touchesForView : (UIView  * )view ;
    -  (NSSet  * )touchesForGestureRecognizer : (UIGestureRecognizer  * )gesture __OSX_AVAILABLE_STARTING (__MAC_NA ,__IPHONE_3_2 ) ;
  • touches 參數自己就是處在當前狀態的UITouch集合
  • 從 touches 集合中隨機獲取一個UITouch
    [touches anyObject];

UITouch 對象的各類屬性 rem

  • timestamp 這個觸控對象最後改變的時間戳。 用從系統啓動到如今的時間來表示,float類型。開始時和移動時會更新。
  • tapCount 連續點擊的次數。一旦中斷就從新計數。
  • phase 這個觸控對象的所處狀態。 枚舉類型。
  • locationInView() 在本身所屬View中的位置。

示例代碼( Metronome by Apple ) it

-  ( void )touchesBegan : (NSSet  * )touches withEvent : (UIEvent  * )event  {

    UITouch *touch = [[event allTouches] anyObject]; io

    lastLocation = [touch locationInView:self]; event

}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [[event allTouches] anyObject];

    CGPoint location = [touch locationInView:self];

       

    CGFloat xDisplacement = location.x - lastLocation.x;

    CGFloat yDisplacement = location.y - lastLocation.y;

    CGFloat xDisplacementAbs = fabs(xDisplacement);

    CGFloat yDisplacementAbs = fabs(yDisplacement);

    // If the displacement is vertical, drag the weight up or down. This will impact the speed of the oscillation.

    if ((xDisplacementAbs  1)) {  

        [self stopSoundAndArm];

        [self dragWeightByYDisplacement:yDisplacement];

        lastLocation = location;

        tempoChangeInProgress = YES;

    } else if (xDisplacementAbs >= yDisplacementAbs) {  

        // If displacement is horizontal, drag arm left or right. This will start oscillation when the touch ends.

        CGFloat radians = atan2f(location.y - kArmBaseY, location.x - kArmBaseX);

        CGFloat rotation = RadiansToDegrees(radians) + 90.0;

        [self rotateArmToDegree:rotation];

    }

}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [[event allTouches] anyObject];

    CGPoint location = [touch locationInView:self];

   

    CGFloat xDisplacement = location.x - lastLocation.x;

    CGFloat yDisplacement = location.y - lastLocation.y;

    CGFloat xDisplacementAbs = fabs(xDisplacement);

    CGFloat yDisplacementAbs = fabs(yDisplacement);

   

    [self stopSoundAndArm];

    if (tempoChangeInProgress) {  

        [self dragWeightByYDisplacement:yDisplacement];

        [self startSoundAndAnimateArmToRight:YES];

        tempoChangeInProgress = NO;

    } else if (xDisplacementAbs > yDisplacementAbs) {

        // horizontal displacement, start oscillation

        BOOL startToRight = (xDisplacement >= 0.0) ? YES : NO;

        [self startSoundAndAnimateArmToRight:startToRight];

    }

}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {

    tempoChangeInProgress = NO;

    [self stopSoundAndArm];

}

相關文章
相關標籤/搜索