天天看點

【我們都愛Paul Hegarty】斯坦福IOS8公開課個人筆記18 Gestures手勢

在之前幾話中我們已經知道了如何去繪制視圖,以及MVC模式的應用和代理的使用,這一話來講一下如何識别手勢,例如縮放(pinches)、旋轉(rotations)、滑動(swopes)、點選(taps)

我們可以獲得手勢的原始資訊,比如起始位置之類的,但是我們很難判斷諸如這是一個滑動還是僅僅單純地向右移動,是以IOS為我們做了底層的封裝。

手勢發生在視圖的邊界内的時候,視圖會識别特定的手勢,有一個叫做UIGestureRecognizer的類,它是一個抽象的基類,通常你不會直接建立這個類,而是建立它的子類,這些子類可以識别某個特定的手勢。

IOS上的手勢識别器有兩個步驟:

1.為視圖添加手勢識别器,表示這個視圖現在可以識别手勢,如果你識别了某個手勢你就報告給某個對象。

2.指定視圖的報告對象

通常為視圖添加一個手勢識别器是控制器來進行的,但是有時候視圖自己也可以添加。

那麼怎麼添加手勢識别器呢,我們會在屬性監測器中來進行,就像我們設定FaceView的代理一樣。

例如示例中展示了一個在一個視圖中增加了一個屬性觀察器,我們的手勢識别器隻識别拖動動作,是以調用了識别器的子類,第一個參數表示,當手勢被識别的時候,向誰發送消息,action表示手勢被識别的時候調用的方法,冒号的意思是這個方法會有一個參數,你也可以不寫冒号,這樣方法被調用的時候就得不到這個參數,而這個參數就是手勢識别器。隻有當你識别滑動手勢的時候不需要參數。

然後我啟動這個手勢識别器,這樣每次在視圖的邊界内識别到手勢的時候就會向控制器發送一個帶參數的pan消息。

那麼有了這個參數後我們能做什麼呢?

在處理拖動的事件的時候我們需要知道它被拖動到的位置,是以手勢識别器的子類針對特定的動作添加了自己特定的方法。你可以得到手指移動的距離,也可以重置這個距離。

手勢識别器有一個特殊的屬性叫做state(狀态),拖動手勢可能會經曆許多個狀态,首先是Possible,表示它或許可能是一個拖動手勢,如果發現動作是一個非連續的手勢,那麼你就得到另一個狀态Recongized,表示動作被識别了,如果手勢是連續的,也就是發生了拖動動作,那麼就會轉入狀态Began,随着手勢的變化會不斷通知事件處理對象,狀态改變為Changed,當手指離開螢幕時就變成Ended,這是一個簡單的狀态機,拖動手勢在狀态機中的狀态就是Possible-Began-Changed-Ended。也有Failed和Cancelled狀态,比如突然一個電話打進來了那麼這個拖動手勢就會被取消掉。是以有時你需要考慮手勢被取消的狀态,有時候就不必。有了這些狀态,那麼手勢識别器是如何工作的呢?

在pan方法中,當手勢移動或者上劃的時候我需要做些事情,當它第一次下滑的時候我不需要做任何事。

fall through在switch中表示目前的函數實作即為下一個case的函數實作,無論下一個函數的實作是什麼,這也意味着我想在Changed和Ended中做同樣的處理。我要做的就是在可拖動視圖的坐标系中,找出pan手勢的位置。然後我更新控制器中依賴于坐标的東西,因為這就是由控制器來控制的。

黃色字型中把視圖置于原點的操作是可選的,你可以讓視圖在下一次拖動手勢被識别的時候沿着目前位置繼續移動,也可以讓它回到原點。

現在來讨論下具體的手勢:

【我們都愛Paul Hegarty】斯坦福IOS8公開課個人筆記18 Gestures手勢

首先是Pinch(縮放),縮放有兩個屬性,首先是比例,初始值為1,當你的指寬增加時這個值會變大,當你的指寬縮小時它會減小。

還有一個屬性是速度,用來訓示縮放的速度快慢。

第二個手勢是Rotation(旋轉),這也是一個兩個手指的動作,像在旋轉一個按鈕一樣,它會告訴你旋轉了多少弧度,也會告訴你每秒轉過的弧度。

接下來是Swipe(滑動),滑動手勢有些不同,當你建立了一個滑動手勢時,傳回到outlet的屬性觀察器中,你需要指定滑動的方向和所使用的手指數量。

最後是Tap(點選)手勢,這個手勢看起來是間斷的,你可以設定點選和觸摸的次數。

在下一話中我們将利用本話的知識為小人臉Demo添加手勢識别功能