The Core iOS CookBook 第一章節學習筆記 - 手勢和觸控

手勢和觸控基礎知識
web

觸摸控制 是 iOS 系統交互的核心方式。設計模式

觸控

Cocoa Touch 以儘量簡單地方式實現了直接的操控。它會把觸控事件發送給你正在進行交互的視圖。spa

每一次觸控都會轉達不少的信息: 觸控發生的位置,點擊屏幕的次數,觸控發生的時間。.net

iOS 使用 responder chain (響應鏈) 來肯定到底是哪一個對象應該對觸控作出響應。 響應者(responders)是響應 事件(event) 的對象。 這些響應者扮演的角色就比如是一串管理者,對這些 事件(event)進行管理。當用戶觸摸屏幕時,應用會去尋找一個對象來處理這一個觸控事件。 觸摸(touch)被傳遞下去,從一個視圖到另一個視圖,直到一些對象來接管而且對這個 事件(event)作出響應。設計

在大多數狀況下,觸摸(touches)以及其信息 被存儲在 UITouch 對象中,觸摸(touches)被做爲一組一組的形式在 UIEvent 對象中傳遞。每個 UIEvent 對象都表明了一個單一的 觸控事件,包含一次或屢次觸摸。這一點既決定了開發者如何去響應用戶的操做,也決定了用戶怎麼在屏幕上進行操做。code

你的應用經過 視圖 或者 視圖控制器 來接收 觸摸(touches)。實現處理 觸摸(touch)的類須要經過繼承 UIResponder 類來實現。 你將會決定在哪兒處理和響應這些 觸摸(touches)。 那些嘗試不使用 responder 類來實現簡單手勢控制的開發新人會遇到不少麻煩。orm

在視圖上處理 觸摸(touches) 看似違反直覺。你可能想去把界面顯示的方式和它對 touches 作出響應的方式分離開。進一步說,視圖直接響應觸控來實現交互看似違反了 MVC 設計模式,可是這樣作是頗有必要的,並且能夠提升封裝性。對象

階段

touches 是具備生命週期的。任意一個 touch 都會經歷五個階段。blog

  1. UITouchPhaseBegan - 當用戶剛接觸屏幕的時候繼承

  2. UITouchPhaseMoved - 當這個接觸動做在屏幕上移動時

  3. UITouchPhaseStationary - 當一個接觸動做在屏幕上中止住時

  4. UITouchPhaseEnded - 當用戶的手指從屏幕上移開時

  5. UITouchPhaseCancelled - 當 iOS 系統中止跟蹤一個 touch 時。 一般發生在,系統中斷或者是視圖從窗口移除或者是處在非激活狀態(有來電)。

這五個階段用來劃分一個觸控事件發生過程當中的整個流程。

觸控和響應方法

全部 UIResponder 類的子類,包括 UIView 和 UIViewController 都會對 touches 作出響應。每個類都決定了自身是否響應或者是如何去響應。當須要去作出響應時,這些類的實例會對用戶的觸控按照本身的方式進行響應。

預約義的回調方法能處理觸控開始,觸控移動,觸控結束這幾種情形。和 階段(Phase)相對應。方法以下:

  1. touchesBegan: withEvent: - 在觸控剛剛發生的時候被調用

  2. touchesMoved: withEvent: - 在觸控移動的時候被調用

  3. touchesEnded: withEvent: - 在觸控結束的時候被調用

  4. touchesCancelled: withEvent: - 當系統強行中斷觸控事件的時候,該方法會被調用(舉例:你正在刷微博,忽然有人來電,該方法就是在此刻被調用的)

上面的每個方法都屬於 UIResponder 方法,一般在 一個 UIView 或是 UIViewController 的子類中進行實現。 這些方法內部並無實現什麼功能。當你想把觸控動做添加到應用時,就應該重載這些方法,實現本身須要的功能。 注意:在UITouchPhaseStationary 階段,沒有方法會被回調。

被觸控的視圖

多點觸控

手勢識別器

經過手勢識別器類,當用戶進行輕擊、縮放、旋轉、橫掃、拖動或是一個長按動做時,咱們能夠觸發回調方法。

幾種常見的手勢 1. Taps - 輕擊,一指或多指 2. Swipes - 橫掃 3. Pinches - 捏縮 4. Rotations - 雙指進行視圖的旋轉 5. Pans - 拖拽進行平移 6. Long presses - 長按

方法1: 添加一個直接操做的界面

當你在處理直接操縱時,你的設計中心會由 UIViewController 移向 UIView. 更確切的說,應該是移向了 UIResponder。你經過自定義一個從UIResponder類中獲取的方法,來建立一個能夠進行觸控的界面。

方法 1-1 這個例子建立了一個 UIImageView類的子類,名爲 DragView,而且把觸控響應添加到了這個子類中。 因爲它是一個圖片視圖,它可以與用戶進行交互就顯得尤其重要(也就是說, setUserInteractionEnabled 屬性必須被設置爲 YES)。這個屬性會影響這個視圖自己以及它全部的子視圖。代碼以下:

    @implementation DragView
    {
        CGPoint startLocation;
    }

    // 初始化方法
    - (id)initWithImage:(UIImage *)image {

        self = [super initWithImage:image];
        if (self) {

            // 在初始化成功後,讓該 DragView 實例對象具有可交互性
            self.userInteractionEnabled = YES;
        }

        return self;
    }

    // Responder 類中的接口方法
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

        // 計算而且存儲偏移量, 把相應觸控的視圖置頂
        startLocation = [[touches anyObject] locationInView:self];
        [self.superview bringSubviewToFront:self];
    }

    // Responder 類中的接口方法
    - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

        // 計算偏移量
        CGPoint point = [[touches anyObject] locationInView:self];
        float dx = point.x - startLocation.x;
        float dy = point.y - startLocation.y;

        // 計算視圖新的中心點座標
        CGPoint newCenter = CGPointMake(self.center.x + dx, self.center.y + dy);

        // 肯定視圖新的位置
        self.center = newCenter;
    }

方法2:利用手勢識別器,實現視圖的手勢控制

知識預備

  1. AffineTransform 仿射變換 - 能夠經過一系列的原子變換的複合來實現,包括:平移(Translation)、縮放(Scale)、翻轉(Flip)、旋轉(Rotation)和錯切(Shear)(圖像的錯切其實是平面景物在投影平面上的非垂直投影)。

  2. iOS 視圖的 frame 和 bounds 屬性的區別: http://blog.csdn.net/mad1989/article/details/8711697

frame: 該view在父view座標系統中的位置和大小。(參照點是,父親的座標系統) bounds:該view在本地座標系統中的位置和大小。(參照點是,本地座標系統,就至關於ViewB本身的座標系統,以0,0點爲起點) center:該view的中心點在父view座標系統中的位置和大小。(參照點是,父親的座標系統)

-(CGRect)frame{
    return CGRectMake(self.frame.origin.x,self.frame.origin.y,self.frame.size.width,self.frame.size.height);
}
-(CGRect)bounds{
    return CGRectMake(0,0,self.frame.size.width,self.frame.size.height);
}

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           Jan 4, 2015

相關文章
相關標籤/搜索