iOS學習筆記(2)— UIView使用者事件響應

來源:互聯網
上載者:User

標籤:

UIView除了負責展示內容給使用者外還負責響應使用者事件。本章主要介紹UIView使用者互動相關的屬性和方法。

1、互動相關的屬性

userInteractionEnabled 預設是YES ,如果設定為NO則不響應使用者事件,並且把當前控制項從事件隊列中刪除。也就是說設定了userInterfaceEnabled屬性的視圖會打斷響應者鏈導致該view的subview都無法響應事件。

multipleTouchEnabled  預設是NO,如果設定為YES則支援多點觸碰。

exclusiveTouch 預設是NO,如果設定為YES則當前UIView會獨佔整個Touch事件。具體來說就是如果UIView設定了exclusiveTouch屬性為YES則當這個UIView成為第一響應者時,在手指離開螢幕前其他view不會響應任何touch事件。

作用舉例:UITableView的每個cell都需要使用exclusive,否則同時點擊多個cell會觸發每個視圖的事件響應。手勢識別會忽略此屬性。

 

2、觸摸響應

瞭解UIView的觸碰響應之前,首先瞭解在iOS中觸碰事件是什麼,事件在視圖模型中是如何傳遞的,視圖在接收到一個事件是如何響應的。下面介紹觸碰事件類別UITouch和響應者鏈來解釋事件的工作原理。

在iOS中UITouch類代表觸碰事件。當使用者觸控螢幕幕後就會產生相應的事件,所有相關的UITouch對象都被封裝在事件中,被程式交由特定的對象處理。UITouch對象包括觸碰的詳細資料。

UITouch含有5個屬性:

window:觸碰產生時所處的視窗,由於視窗可能發生變化,當前所在的視窗不一定是最開始的視窗。

view:觸碰產生時所處的視圖。由於視圖可能發生變化,當前視圖也不一定是最初的視圖。

tapCount:短時間內輕擊(tap)螢幕的次數,可根據tapCount判斷單擊、雙擊或更多的輕擊。

timestamp:時間戳記錄了觸碰事件產生或變化時的時間。單位是秒。

phase:觸碰事件在螢幕上有一個周期,即觸碰開始、觸碰點移動、觸碰結束,中途取消。通過phase可以查看當前觸碰事件在一個周期中所處的狀態。UITouchPhase枚舉:

UITouchPhaseBegan

UITouchPhaseMoved

UITouchPhaseStationary

UITouchPhaseEnded

UITouchPhaseCancelled

 

當手指觸碰到螢幕,無論是單點還是多點觸碰,事件都會開始,直到使用者所有的手指都離開螢幕。期間所有的UITouch對象都被封裝在UIEvent事件對象中,由程式分發給處理者。事件記錄了這個周期中所有觸碰對象狀態的變化。

只要螢幕被觸摸,系統會將諾幹個觸碰資訊封裝到UIEvent對象中發送給程式,由管理程式UIApplication對象將事件分發。

 

響應者對象就是可以響應事件並對事件作出處理的對象。在iOS中UIResponder類定義了響應者對象的所有方法。UIApplication、UIWindow、UIViewController、UIView以及UIKit中繼承自UIView的控制項都間接或直接繼承自UIResponder類,這些類都可以當做響應者。

響應者鏈表示一系列響應者對象組成的事件傳遞的鏈條。當確定了第一響應者後,事件交由第一響應者處理,如果第一響應者不處理事件沿著響應者鏈傳遞,交給下一個響應者。一般來說,第一響應者是UIView對象或者UIView的子類對象,當其被觸摸後事件交由它處理,如果它不處理,事件就會交給它的UIViewController處理(如果存在),然後是它的superview父視圖對象,以此類推,直到頂層視圖。如果頂層視圖不處理則交給UIWindow對象處理,再到UIApplication對象(如果UIApplication繼承自UIResponder)。如果整個響應者鏈都不響應這個事件則該事件被丟棄。

 

UIView類繼承了UIResponder類,要對事件作出處理還需要重寫UIResponder類中定義的事件處理函數。根據不同的觸碰狀態,程式會調用相應的處理函數,這些函數包括:

-(void) touchesBegan:(NSSet *)touches withEvents:(UIEvent *)event;

-(void) touchesMoved:(NSSet *)touches withEvents:(UIEvent *)event;

-(void) touchesEnded:(NSSet *)touches withEvents:(UIEvent *)event;

-(void) touchesCancelled:(NSSet *)touches withEvents:(UIEvent *)event;

 

這幾個方法被調用時,對應了UITouch類中的phase屬性的4個枚舉值。當觸碰被取消,如觸碰過程中被來電打斷,會調用touchesCancelled:touches:方法。

這些方法在開發中並不需要全部實現,可以根據需要重寫特定的方法。這4個方法都有兩個相同的參數:NSSet類型的touches和UIEvent類型的event。Touches表示觸碰產生的所有的UITouch對象,event表示事件。因為UIEvent包含了整個觸碰過程中所有的觸碰對象,所以可以調用allTouches 方法擷取該事件內所有觸碰對象,也可以調用touchesForView;或者touchesForWindows;取出特定視圖或者視窗上的觸碰對象。在這幾個事件中,都可以拿到觸碰對象,然後根據其位置、狀態、時間屬性做邏輯處理。

 

輕擊操作很容易引起歧義,比如使用者點擊了一次之後,並不知道使用者是想單擊還是只是雙擊的一部分,或者點了兩次之後並不知道使用者是想雙擊還是繼續點擊。可以使用延遲調用函數解決這個問題。

 

[objc] view plaincopyprint? 
  1. -(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event  
  2. {  
  3.   
  4.   UITouch *touch = [touches anyObject];  
  5.           if (touch.tapCount == 1)  
  6.          {  
  7.                  [self performSelector:@selector(setBackground:) withObject:[UIColor blueColor] afterDelay:2];  
  8.   
  9.           }  
  10.           else if(touch.tapCount == 2)  
  11.           {  
  12.                  [self cancelPreviousPerformRequestsWIthTarget:self              selector:@selector(setBackground:) object:[UIColor blueColor]];  
  13.                  self.view.backgroundColor = [UIColor redColor];  
  14.            }  
  15.   }      

 

除了觸碰事件外UIResponder還提供了運動事件的支援。

運動事件的方法:

-(void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event 搖動事件開始

-(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event 搖動事件結束

-(void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event  搖動事件被中斷

 

遠程事件:

-(void)remoteControlReceivedWithEvent: 音樂後台播放控制的時候會用到

 

第一響應者的相關函數:

- (BOOL)canBecomeFirstResponder    預設返回NO

- (BOOL)becomeFirstResponder

- (BOOL)canResignFirstResponder    預設返回YES

- (BOOL)resignFirstResponder;

- (BOOL)isFirstResponder

可以通過becomeFirstResponder方法註冊成為第一響應者,通過resignFirstResponder方法不成為第一響應者。比如通過這兩個方法操作UITextField來修飾鍵盤的現隱藏。

 

3、手勢

UIView關於手勢的方法:

-(void) addGestureRecognizer:(UIGestureRecognizer *)gestureRecognizer  增加一個手勢。

-(void) removeGestureRecognizer:(UIGestureRecognizer *)getureRecognizer 刪除一個手勢。

-(BOOL) gestureRecognizerShouldBegan:(UIGestureRecognizer *)gestureRecognizer 詢問是否開始執行該手勢,預設返回YES。

手勢相比觸碰事件的好處是可以直接使用已經定義好的手勢,開發人員不用自己計算手指移動軌跡。

UIGestureRecognizer是一個手勢基類,提供了簡單的手勢實現方式。衍生類如下:

UITabGestureRecognizer         輕擊手勢

UIPinchGestureRecognizer       捏合手勢

UIRotationGestureRecognizer    旋轉手勢

UISwipeGestureRecognizer  撥動手勢

UIPanGestureRecognizer 拖拽手勢

UILongPressGestrueRecognizer 長按手勢

 

UIGestureRecognizer主要方法:

-(id) initWithTarget:action: 初始化方法

-(void)addTarget:action:   

-(void)removeTarget:action: 

主要屬性:

UIGestureRecognizerState state 手勢識別目前狀態

有以下幾種情況:

UIGestureRecognizerStatePossibel,  未識別狀態

UIGestureRecognizerStateBegan,     手勢開始

UIGestureRecognizerStateChanged,  手勢改變

UIGestureRecognizerStateEnded, 手勢結束

UIGestureRecognizerStateFailured 手勢失敗,被其他事件中斷。

 

UITabGestureRecognizer  輕擊手勢任意手指任意次數的點擊

屬性:

numberOfTapsRequired 點擊次數

numberOfTouchesRequired 手指個數  

 

UIPinchGestureRecognizer  捏合或者擴張手勢

屬性:

scale:初始值為1,兩手指距離減少則scale不斷變小;兩個手指重合則變為0;

velocity:初始值為0,手指移動的相對速度,兩手指距離減少為負數,速度越快數值越少;兩手指距離變大為整數,速度越快數值越大。

 

UIRotationGestureRecognizer 旋轉手勢

屬性:

rotation:初始值為0,兩手指的旋轉弧度,順時針旋轉為正數,逆時針旋轉為負數。

velocity:初始值為0手指一動的相對速度,順時針為正數越快值越大;逆時針為負越快越小。

 

UISwipGestureRecognizer 撥動手勢,一個手勢只能指定一個方向,如果需要指定多個方向需要多個手勢

屬性:

numberOfTouchesRequired: 手指個數

direction:手勢方向,如UISwipeGestureRecognizerDirectionRight 向右

 

UIPanGestureRecognizer:  拖拽手勢,相比撥動手勢,手指與螢幕的互動時間更長。

屬性:

mininumNumberOfTouches:預設值為1,最少手指數量

maxnumNumberOfTouches:最大手指數量

 

UILongPressGestrueRecognizer: 長按手勢。

屬性:

numberOfTapsRequired:預設值為0,輕擊的次數。

numberOfTouchesRequired:預設值是1,手指數量。

mininumPressDuration:預設值為0.5,單位是秒。

allowableMovement:預設值為10,單位是像素。

iOS學習筆記(2)— UIView使用者事件響應

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.