UIView的用戶事件響應(yīng)

UIView除了負責展示內(nèi)容給用戶外還負責響應(yīng)用戶事件。本章主要介紹UIView用戶交互相關(guān)的屬性和方法沮脖。

1、交互相關(guān)的屬性

userInteractionEnabled默認是YES?腐泻,如果設(shè)置為NO則不響應(yīng)用戶事件窄做,并且把當前控件從事件隊列中刪除吃衅。也就是說設(shè)置了userInterfaceEnabled屬性的視圖會打斷響應(yīng)者鏈導(dǎo)致該view的subview都無法響應(yīng)事件往踢。

multipleTouchEnabled默認是NO,如果設(shè)置為YES則支持多點觸碰徘层。

exclusiveTouch默認是NO峻呕,如果設(shè)置為YES則當前UIView會獨占整個Touch事件。具體來說就是如果UIView設(shè)置了exclusiveTouch屬性為YES則當這個UIView成為第一響應(yīng)者時趣效,在手指離開屏幕前其他view不會響應(yīng)任何touch事件瘦癌。

作用舉例:UITableView的每個cell都需要使用exclusive,否則同時點擊多個cell會觸發(fā)每個視圖的事件響應(yīng)跷敬。手勢識別會忽略此屬性讯私。

2、觸摸響應(yīng)

了解UIView的觸碰響應(yīng)之前西傀,首先了解在iOS中觸碰事件是什么斤寇,事件在視圖模型中是如何傳遞的,視圖在接收到一個事件是如何響應(yīng)的拥褂。下面介紹觸碰事件類UITouch和響應(yīng)者鏈來解釋事件的工作原理娘锁。

在iOS中UITouch類代表觸碰事件。當用戶觸摸屏幕后就會產(chǎn)生相應(yīng)的事件饺鹃,所有相關(guān)的UITouch對象都被包裝在事件中莫秆,被程序交由特定的對象處理。UITouch對象包括觸碰的詳細信息悔详。

UITouch含有5個屬性:

window:觸碰產(chǎn)生時所處的窗口镊屎,由于窗口可能發(fā)生變化,當前所在的窗口不一定是最開始的窗口伟端。

view:觸碰產(chǎn)生時所處的視圖杯道。由于視圖可能發(fā)生變化,當前視圖也不一定是最初的視圖。

tapCount:短時間內(nèi)輕擊(tap)屏幕的次數(shù)党巾,可根據(jù)tapCount判斷單擊萎庭、雙擊或更多的輕擊。

timestamp:時間戳記錄了觸碰事件產(chǎn)生或變化時的時間齿拂。單位是秒抹缕。

phase:觸碰事件在屏幕上有一個周期痕钢,即觸碰開始、觸碰點移動、觸碰結(jié)束恼除,中途取消。通過phase可以查看當前觸碰事件在一個周期中所處的狀態(tài)阳似。UITouchPhase枚舉:

UITouchPhaseBegan

UITouchPhaseMoved

UITouchPhaseStationary

UITouchPhaseEnded

UITouchPhaseCancelled

當手指觸碰到屏幕权她,無論是單點還是多點觸碰,事件都會開始刀森,直到用戶所有的手指都離開屏幕踱启。期間所有的UITouch對象都被封裝在UIEvent事件對象中,由程序分發(fā)給處理者研底。事件記錄了這個周期中所有觸碰對象狀態(tài)的變化埠偿。

只要屏幕被觸摸,系統(tǒng)會將諾干個觸碰信息封裝到UIEvent對象中發(fā)送給程序榜晦,由管理程序UIApplication對象將事件分發(fā)冠蒋。

響應(yīng)者對象就是可以響應(yīng)事件并對事件作出處理的對象。在iOS中UIResponder類定義了響應(yīng)者對象的所有方法乾胶。UIApplication抖剿、UIWindow、UIViewController识窿、UIView以及UIKit中繼承自UIView的控件都間接或直接繼承自UIResponder類牙躺,這些類都可以當做響應(yīng)者。

響應(yīng)者鏈表示一系列響應(yīng)者對象組成的事件傳遞的鏈條腕扶。當確定了第一響應(yīng)者后孽拷,事件交由第一響應(yīng)者處理,如果第一響應(yīng)者不處理事件沿著響應(yīng)者鏈傳遞半抱,交給下一個響應(yīng)者脓恕。一般來說,第一響應(yīng)者是UIView對象或者UIView的子類對象窿侈,當其被觸摸后事件交由它處理炼幔,如果它不處理,事件就會交給它的UIViewController處理(如果存在)史简,然后是它的superview父視圖對象乃秀,以此類推,直到頂層視圖。如果頂層視圖不處理則交給UIWindow對象處理跺讯,再到UIApplication對象(如果UIApplication繼承自UIResponder)枢贿。如果整個響應(yīng)者鏈都不響應(yīng)這個事件則該事件被丟棄。

UIView類繼承了UIResponder類刀脏,要對事件作出處理還需要重寫UIResponder類中定義的事件處理函數(shù)局荚。根據(jù)不同的觸碰狀態(tài),程序會調(diào)用相應(yīng)的處理函數(shù)愈污,這些函數(shù)包括:

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

這幾個方法被調(diào)用時耀态,對應(yīng)了UITouch類中的phase屬性的4個枚舉值。當觸碰被取消暂雹,如觸碰過程中被來電打斷首装,會調(diào)用touchesCancelled:touches:方法。

這些方法在開發(fā)中并不需要全部實現(xiàn)杭跪,可以根據(jù)需要重寫特定的方法簿盅。這4個方法都有兩個相同的參數(shù):NSSet類型的touches和UIEvent類型的event。Touches表示觸碰產(chǎn)生的所有的UITouch對象揍魂,event表示事件。因為UIEvent包含了整個觸碰過程中所有的觸碰對象棚瘟,所以可以調(diào)用allTouches?方法獲取該事件內(nèi)所有觸碰對象现斋,也可以調(diào)用touchesForView;或者touchesForWindows;取出特定視圖或者窗口上的觸碰對象。在這幾個事件中偎蘸,都可以拿到觸碰對象庄蹋,然后根據(jù)其位置、狀態(tài)迷雪、時間屬性做邏輯處理限书。

輕擊操作很容易引起歧義,比如用戶點擊了一次之后章咧,并不知道用戶是想單擊還是只是雙擊的一部分倦西,或者點了兩次之后并不知道用戶是想雙擊還是繼續(xù)點擊×扪希可以使用延遲調(diào)用函數(shù)解決這個問題扰柠。


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

? ? ? ?UITouch *touch = [touches anyObject];

? ? ? if(touch.tapCount == 1) ?{

? ? ? ? ? ? [selfperformSelector:@selector(setBackground:) withObject:[UIColor blueColor] afterDelay:2];
}

elseif(touch.tapCount == 2)

{

[selfcancelPreviousPerformRequestsWIthTarget:selfselector:@selector(setBackground:) object:[UIColor blueColor]];

self.view.backgroundColor = [UIColor redColor];

}

}


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

運動事件的方法:

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

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

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

遠程事件:

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

第一響應(yīng)者的相關(guān)函數(shù):

-?(BOOL)canBecomeFirstResponder默認返回NO

-?(BOOL)becomeFirstResponder

-?(BOOL)canResignFirstResponder默認返回YES

-?(BOOL)resignFirstResponder;

-?(BOOL)isFirstResponder

可以通過becomeFirstResponder方法注冊成為第一響應(yīng)者疼约,通過resignFirstResponder方法不成為第一響應(yīng)者卤档。比如通過這兩個方法操作UITextField來控制鍵盤的現(xiàn)隱藏。

3程剥、手勢

屬性:

NSArray *gestureRecognizers

可以通過這個屬性獲取當前UIView的所有手勢對象劝枣。手勢在觸碰事件處理流程中,處于觀察者的角色,其不是view層級結(jié)構(gòu)的一部分舔腾,所以不參與響應(yīng)者鏈溪胶。在將觸摸事件發(fā)送給hit-test view之前,系統(tǒng)會先將觸碰事件發(fā)送到view綁定的Gesture Recognizer上琢唾。

UIView關(guān)于手勢的方法:

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

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

-(BOOL)?gestureRecognizerShouldBegan:(UIGestureRecognizer?*)gestureRecognizer詢問是否開始執(zhí)行該手勢采桃,默認返回YES懒熙。

手勢相比觸碰事件的好處是可以直接使用已經(jīng)定義好的手勢,開發(fā)者不用自己計算手指移動軌跡普办。手勢識別的基類是UIGestureRecognizer工扎,是一個抽象類,定義了實現(xiàn)底層手勢識別行為的編程接口衔蹲。衍生類如下:

UITabGestureRecognizer輕擊手勢

UIPinchGestureRecognizer捏合手勢

UIRotationGestureRecognizer旋轉(zhuǎn)手勢

UISwipeGestureRecognizer輕掃手勢

UIPanGestureRecognizer拖拽手勢

UILongPressGestrueRecognizer長按手勢

UIGestureRecognizer主要方法:

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

-(void)addTarget:action:

-(void)removeTarget:action:

主要屬性:

UIGestureRecognizerState?state手勢識別當前狀態(tài)

有以下幾種情況:

UIGestureRecognizerStatePossibel,? 未識別狀態(tài)

UIGestureRecognizerStateBegan,???? 手勢開始

UIGestureRecognizerStateChanged,? 手勢改變

UIGestureRecognizerStateEnded, 手勢結(jié)束

UIGestureRecognizerStateFailured手勢失敗肢娘,被其他事件中斷。當把手勢state設(shè)為這個值得時候相當于取消了這個手勢舆驶。

cancelsTouchesInView為YES時橱健,表示當Gesture Recognizers識別到手勢后,會向hit-test view發(fā)送touchesCancelled:消息以取消hit-test view對觸碰序列的處理沙廉,這樣只有Gesture Recognizer響應(yīng)此次觸碰拘荡,響應(yīng)者鏈的view不再響應(yīng)。如果為NO撬陵,則不發(fā)送touchesCancelled:消息珊皿,這樣Gesture Recognizer和view同時響應(yīng)觸碰事件。默認值是YES巨税。

delaysTouchesBegan為NO時表示觸碰序列已經(jīng)開始而手勢識別還未識別出此手勢時蟋定,touch事件會同時發(fā)給hit-test view。如果為YES草添,則手勢在識別過程中驶兜,不會有任何觸碰事件發(fā)送給hit-test view;如果手勢識別器最終識別了手勢远寸,則也不會發(fā)送任何消息給hit-test view促王;如果手勢識別器最終沒有識別到手勢,才會發(fā)送所有觸碰事件給view處理而晒。默認值是NO蝇狼。

delaysTouchesBegan為YES時,延遲發(fā)送touchesEnded:消息倡怎,手勢失敗時才發(fā)送迅耘。默認值是YES贱枣。

UITabGestureRecognizer輕擊手勢任意手指任意次數(shù)的點擊

屬性:

numberOfTapsRequired點擊次數(shù)

numberOfTouchesRequired手指個數(shù)

UIPinchGestureRecognizer捏合或者擴張手勢

屬性:

scale:初始值為1,兩手指距離減少則scale不斷變胁ā纽哥;兩個手指重合則變?yōu)?;

velocity:初始值為0栖秕,手指移動的相對速度春塌,兩手指距離減少為負數(shù),速度越快數(shù)值越少簇捍;兩手指距離變大為整數(shù)只壳,速度越快數(shù)值越大。

UIRotationGestureRecognizer旋轉(zhuǎn)手勢

屬性:

rotation:初始值為0暑塑,兩手指的旋轉(zhuǎn)弧度吼句,順時針旋轉(zhuǎn)為正數(shù),逆時針旋轉(zhuǎn)為負數(shù)事格。

velocity:初始值為0手指一動的相對速度惕艳,順時針為正數(shù)越快值越大;逆時針為負越快越小驹愚。

UISwipGestureRecognizer輕掃手勢远搪,一個手勢只能指定一個方向,如果需要指定多個方向需要多個手勢

屬性:

numberOfTouchesRequired:?手指個數(shù)

direction:手勢方向逢捺,如UISwipeGestureRecognizerDirectionRight 向右

UIPanGestureRecognizer:??拖拽手勢谁鳍,相比輕掃手勢,手指與屏幕的交互時間更長蒸甜。

屬性:

mininumNumberOfTouches默認值為1,最少手指數(shù)量

maxnumNumberOfTouches最大手指數(shù)量

方法:

- (CGPoint)velocityInView:(UIView *)view返回拖拽手勢的速度余佛,值是每秒移過的point值柠新,被分成水平和垂直兩個分量。

UILongPressGestrueRecognizer:?長按手勢辉巡。

屬性:

numberOfTapsRequired:默認值為0恨憎,輕擊的次數(shù)。

numberOfTouchesRequired:默認值是1郊楣,手指數(shù)量憔恳。

mininumPressDuration:默認值為0.5,單位是秒净蚤。

allowableMovement:默認值為10钥组,單位是像素pixels。

多手勢兼容

可以為View添加多個手勢今瀑,缺省情況下程梦,沒有對手勢的執(zhí)行順序排序点把,每次調(diào)用順序可能都不同。通過以下方法可以控制手勢的響應(yīng)順序屿附。

- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer

在作為參數(shù)的GestureRecognizer失敗以后手勢才發(fā)生郎逃,否則手勢從不會發(fā)生。

[self.panRecognizer requireGestureRecognizerToFail:self.swipeRecognizer];捏合手勢失敗后才會觸發(fā)拖拽手勢挺份。如果捏合手勢成功則拖拽手勢永遠不會被觸發(fā)

- (BOOL)canBePreventedByGestureRecognizer:(UIGestureRecognizer *)preventingGestureRecognizer

這個方法可以重載褒翰,比如UIGestureRecognizer的子類重載了這個方法返回NO,也就是說無論任何情況下子類的手勢都不能被阻止匀泊,是非常強勢的手勢优训。

如果返回YES,那么preventingGestureRecognizer傳入的手勢就會組織子類手勢探赫。比如:

[rotationGestureRecognizer canBePreventedByGestureRecognizer:pinchGestureRecognizer];如果rotation手勢重載了canBePreventedByGestureRecognizer方法并且返回YES型宙。則旋轉(zhuǎn)手勢被捏合手勢阻止,但是旋轉(zhuǎn)手勢不能阻止捏合手勢伦吠。

還可以在方法體中加入邏輯判斷妆兑。

- (BOOL)canPreventGestureRecognizer:(UIGestureRecognizer *)preventedGestureRecognizer

這個方法同樣可以重載,如果返回NO則這個手勢不能阻止其他任何手勢毛仪。

如果返回YES搁嗓,就可以阻止preventedGestureRecognizer的手勢。比如:

[rotationGestureRecognizer canPreventGestureRecognizer:pinchGestureRecognizer]; ?如果rotation手勢重載了canBePreventedByGestureRecognizer方法并且返回YES箱靴。則旋轉(zhuǎn)手勢阻止了捏合手勢腺逛。

UIGestureRecognizerDelegate

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer

此方法在gesture recognizer視圖傳出UIGestureRecognizerStatePossible狀態(tài)時調(diào)用,如果返回NO衡怀,則轉(zhuǎn)換成UIGestureRecognizerStateFailed棍矛;如果返回YES,則繼續(xù)識別抛杨。默認返回YES

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch

此方法在window對象有觸碰事件發(fā)生時够委,touchesBegan:withEvent:方法之前調(diào)用。如果返回NO怖现,則GestureRecognizer忽略此觸碰事件茁帽。默認返回YES∏停可以用于禁止某個區(qū)域的手勢潘拨。

-?(BOOL)gestureRecognizer:(UIGestureRecognizer?*)gestureRecognizer?shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer?*)otherGestureRecognizer;

如果有多個手勢接收到了同一個消息,該回調(diào)方法決定當前手勢是否要響應(yīng)該事件饶号,如果返回YES則該事件被響應(yīng)铁追,如果返回NO該事件將被忽略

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市茫船,隨后出現(xiàn)的幾起案子脂信,更是在濱河造成了極大的恐慌癣蟋,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,039評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狰闪,死亡現(xiàn)場離奇詭異疯搅,居然都是意外死亡,警方通過查閱死者的電腦和手機埋泵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評論 3 395
  • 文/潘曉璐 我一進店門幔欧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人丽声,你說我怎么就攤上這事礁蔗。” “怎么了雁社?”我有些...
    開封第一講書人閱讀 165,417評論 0 356
  • 文/不壞的土叔 我叫張陵浴井,是天一觀的道長。 經(jīng)常有香客問我霉撵,道長磺浙,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評論 1 295
  • 正文 為了忘掉前任徒坡,我火速辦了婚禮撕氧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘喇完。我一直安慰自己伦泥,他們只是感情好,可當我...
    茶點故事閱讀 67,892評論 6 392
  • 文/花漫 我一把揭開白布锦溪。 她就那樣靜靜地躺著不脯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪刻诊。 梳的紋絲不亂的頭發(fā)上防楷,一...
    開封第一講書人閱讀 51,692評論 1 305
  • 那天,我揣著相機與錄音坏逢,去河邊找鬼域帐。 笑死赘被,一個胖子當著我的面吹牛是整,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播民假,決...
    沈念sama閱讀 40,416評論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼浮入,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了羊异?” 一聲冷哼從身側(cè)響起事秀,我...
    開封第一講書人閱讀 39,326評論 0 276
  • 序言:老撾萬榮一對情侶失蹤彤断,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后易迹,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宰衙,經(jīng)...
    沈念sama閱讀 45,782評論 1 316
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,957評論 3 337
  • 正文 我和宋清朗相戀三年睹欲,在試婚紗的時候發(fā)現(xiàn)自己被綠了供炼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,102評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡窘疮,死狀恐怖袋哼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情闸衫,我是刑警寧澤涛贯,帶...
    沈念sama閱讀 35,790評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站蔚出,受9級特大地震影響弟翘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜身冬,卻給世界環(huán)境...
    茶點故事閱讀 41,442評論 3 331
  • 文/蒙蒙 一衅胀、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧酥筝,春花似錦滚躯、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至宙帝,卻和暖如春丧凤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背步脓。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評論 1 272
  • 我被黑心中介騙來泰國打工愿待, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人靴患。 一個月前我還...
    沈念sama閱讀 48,332評論 3 373
  • 正文 我出身青樓仍侥,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鸳君。 傳聞我的和親對象是個殘疾皇子农渊,可洞房花燭夜當晚...
    茶點故事閱讀 45,044評論 2 355

推薦閱讀更多精彩內(nèi)容

  • UIView用戶事件響應(yīng) UIView除了負責展示內(nèi)容給用戶外還負責響應(yīng)用戶事件。本章主要介紹UIView用戶交互...
    subite0閱讀 256評論 0 1
  • 原文地址:http://www.cnblogs.com/zy1987/p/3195645.html?utm_sou...
    默默_David閱讀 962評論 0 0
  • 在iOS開發(fā)中經(jīng)常會涉及到觸摸事件或颊。本想自己總結(jié)一下砸紊,但是遇到了這篇文章传于,感覺總結(jié)的已經(jīng)很到位,特此轉(zhuǎn)載醉顽。作者:L...
    WQ_UESTC閱讀 6,012評論 4 26
  • 好奇觸摸事件是如何從屏幕轉(zhuǎn)移到APP內(nèi)的沼溜?困惑于Cell怎么突然不能點擊了?糾結(jié)于如何實現(xiàn)這個奇葩響應(yīng)需求游添?亦或是...
    Lotheve閱讀 57,152評論 51 599
  • 今天一天狀態(tài)還不錯盛末,很多事情也都高效的處理完了,還得空看了幾篇文章否淤,看文章都是看看當時有感受就過了悄但,沒有去寫讀書筆...
    Hi_張閱讀 99評論 0 0