事件處理-知識(shí)點(diǎn)
-
1> 事件處理簡介
- PPT簡介
- 3大事件:主要了解觸摸事件胧后。
- 什么是響應(yīng)者對(duì)象
- 為什么繼承UIResponder就能處理事件
- 想處理觸摸事件,應(yīng)該怎么辦
-
2> view拖拽演練
- 為什么要自定義view:系統(tǒng)自帶不能處理事件
- 演示觸摸事件方法,觸摸的完整過程抱环。
- 介紹參數(shù)(NSSet,UITouch,UIEvent)
- 重點(diǎn)UITouch壳快,
- 1.觸摸事件方法中的UITouch都是同一個(gè)對(duì)象,因?yàn)橐桓种笇?duì)應(yīng)一個(gè)UITouch.當(dāng)手指移動(dòng)或者抬起镇草,并不會(huì)產(chǎn)生一個(gè)新的UITouch對(duì)象給你眶痰,而是改變UITouch里面的屬性,
- 2.默認(rèn)三個(gè)方法里面只能獲取到一個(gè)手指梯啤,為什么竖伯。UIView不支持多點(diǎn)觸控
- 3.怎么才能有兩個(gè)手指,兩個(gè)手指同時(shí)按因宇,并且視圖支持多點(diǎn)觸控
- 4.UITouch的tapCount有什么用七婴?可以判斷用戶當(dāng)前是雙擊還是單擊
- 5.UITouch的phase有什么用? 根據(jù)這個(gè)屬性,判斷當(dāng)前需要調(diào)用哪個(gè)處理事件方法察滑,begin,move,end
程序思路:
* 在TouchMove里面做事情-為什么?因?yàn)橛脩羰种冈谝晥D上移動(dòng)的時(shí)候才需要移動(dòng)視圖打厘。
* 獲取用戶當(dāng)前的位置,獲取用戶之前的位置贺辰,就知道用戶從哪移動(dòng)到哪,這個(gè)位置也是視圖移動(dòng)的位置
* 當(dāng)前視圖的位置 = 上一次視圖的位置 + 手指的偏移量
- 3> 事件傳遞
- PPT簡介(學(xué)事件傳遞户盯,誰有權(quán)利處理事件)
- 事件,加入到一個(gè)由誰管理的事件隊(duì)列中?UIApplication
- 為什么用隊(duì)列饲化,不用棧莽鸭。隊(duì)列先進(jìn)先出,意味著先產(chǎn)生的事件吃靠,先處理硫眨。
- 代碼驗(yàn)證事件誰處理
- PPT上這么多view,驗(yàn)證哪個(gè)view處理事件巢块。這么多view捺球,都需要監(jiān)重寫一個(gè)方法,搞個(gè)父類夕冲。
- 一個(gè)view能處理事件氮兵,意味著事件傳遞給他了,那怎么傳遞? 事件是由父控件傳遞給子控件歹鱼。
- 父控件不處理事件泣栈,子控件也不能。藍(lán)色不接收事件弥姻,黃色也不會(huì)接收事件? 為什么南片,因?yàn)槭录菑母缚丶鬟f給子控件的。父控件都沒有事件庭敦,怎么傳給子控件疼进。
- 代碼驗(yàn)證view不能處理事件
- 一個(gè)view怎么不能處理事件。userInteractionEnabled = NO秧廉,hidden = YES伞广,alpha <= 0.01
- 代碼驗(yàn)證UIImageView不允許交互
- UIImageView默認(rèn)不允許用戶交互拣帽,因此默認(rèn)它上面的子控件不能接收事件。
- 怎么找到最合適的View嚼锄?通過一個(gè)遞歸减拭。
- 第一個(gè)接收事件的控件是誰?窗口
- 當(dāng)事件傳遞給窗口的時(shí)候,就會(huì)讓窗口去找最合適的view,1> 判斷自己能不能接收事件 2> 點(diǎn)在不在窗口上 3> 去找比自己更合適的view区丑,從后往前遍歷子控件拧粪,拿到子控件后,把事件傳遞給這個(gè)子控件 4> 子控件拿到事件之后沧侥,又會(huì)做同樣的判斷可霎,一直遞歸去找,直到找到最合適的view.
- 事件傳遞的目的何在?找到最合適的view,把事件交給他宴杀。
- 4> hitText方法和pointInside方法(復(fù)制:02-事件傳遞代碼)
- (了解hitText)學(xué)習(xí)一個(gè)方法必須了解:什么時(shí)候調(diào)用和這個(gè)方法有什么用
- hitText什么時(shí)候調(diào)用:當(dāng)一個(gè)事件傳遞給一個(gè)控件的時(shí)候癣朗,控件就會(huì)調(diào)用這個(gè)方法
- hitText作用: 尋找到最合適的view。
- (回顧下事件傳遞)婴氮,UIApplication -> UIWindow
- UIWindow去尋找最合適的view? [UIWindow hitTest:withEvent:]里面做了什么事情斯棒?
- 1> 判斷窗口能不能處理事件? 如果不能,意味著窗口不是最合適的view主经,而且也不會(huì)去尋找比自己更合適的view,直接返回nil,通知UIApplication荣暮,沒有最合適的view。
- 2> 判斷點(diǎn)在不在窗口
- 3> 遍歷自己的子控件罩驻,尋找有沒有比自己更合適的view
- 4> 如果子控件不接收事件穗酥,意味著子控件沒有找到最合適的view,然后返回nil,告訴窗口沒有找到更合適的view,窗口就知道沒有比自己更合適的view,就自己處理事件。
- 驗(yàn)證下hitTest方法返回nil惠遏,里面的子控件能處理事件嗎砾跃? 重寫根控制器view的hitTest:withEvent:方法,
- 驗(yàn)證這個(gè)方法是否真能找到最合適的view节吮?
- 如果點(diǎn)擊屏幕任何一個(gè)地方抽高,都是白色的view,怎么做透绩。直接返回白色的view,就不會(huì)繼續(xù)去找白色view的子控件了翘骂。
- 介紹pointInside方法
- pointInside作用:判斷一個(gè)點(diǎn)在不在一個(gè)控件上
- point參數(shù):方法調(diào)用者坐標(biāo)系上的點(diǎn),PPT畫圖分析原理帚豪。
- 這節(jié)課的重點(diǎn):學(xué)習(xí)完了pointInside,就能實(shí)現(xiàn)下hitTest方法底層是怎么做的了碳竟。
- 5> hitText練習(xí)
- 分析思路:如果一個(gè)點(diǎn),同時(shí)在黃色view和按鈕上狸臣,由按鈕處理事件莹桅,怎么做?
- 分析事件傳遞: 當(dāng)黃色要處理事件,首先事件得傳遞到他身上
- 重寫hitTest方法:事件傳遞到某個(gè)控件烛亦,調(diào)用什么方法?hitTest
- 返回nil什么意思诈泼?如果直接返回nil懂拾,意味著黃色的view,沒有找到最合適的view,他的父控件厂汗,就會(huì)遍歷下一個(gè)控件委粉,也就是按鈕呜师,詢問按鈕是不是最合適的view.
- 判斷點(diǎn)在不在按鈕上娶桦,在就交給他處理。
- pointInside實(shí)現(xiàn)汁汗。
-
6> 響應(yīng)者鏈條(復(fù)制:02-事件傳遞代碼)
- PPT簡介(學(xué)了響應(yīng)者鏈條衷畦,目的知道誰最終處理事件。)
- touch默認(rèn)做法:自己不處理事件知牌,交給上一個(gè)響應(yīng)者處理touch事件祈争。
- 響應(yīng)者鏈條,點(diǎn)擊綠色的view,如果不處理事件角寸,就會(huì)往上傳遞菩混。
- 驗(yàn)證touch的默認(rèn)做法 先恢復(fù)所有view的默認(rèn)做法
- 監(jiān)聽黃色點(diǎn)擊,藍(lán)色點(diǎn)擊扁藕。
- 黃色調(diào)用默認(rèn)做法沮峡,事件傳遞給誰處理?藍(lán)色
- 得出結(jié)論:
- 1> touch的默認(rèn)做法:自己不處理,交給上一個(gè)響應(yīng)者亿柑。
- 2> 上一個(gè)響應(yīng)者默認(rèn)是父控件
- 兩個(gè)view怎么同時(shí)處理事件?一個(gè)view處理方法邢疙,在調(diào)用父類默認(rèn)的做法
- 把事件傳遞給白色的view,怎么做?
- 總結(jié)下事件傳遞的完整過程.
- 把事件傳遞給控制器望薄,測試白色view的上一個(gè)響應(yīng)者是否是控制器疟游。
- 回顧響應(yīng)者鏈條
7> 抽屜效果
添加子視圖
- 簡單的滑動(dòng)效果
- 監(jiān)聽控制器處理事件方法
- 獲取x軸偏移量
- 改變主視圖的frame
- 利用KVO做視圖切換
往左移動(dòng),顯示右邊痕支,隱藏左邊
往右移動(dòng)颁虐,顯示左邊,隱藏右邊 - 復(fù)雜的滑動(dòng)效果卧须,PPT講解(根據(jù)手指每移動(dòng)一點(diǎn)另绩,x軸的偏移量算出當(dāng)前視圖的frame)
假設(shè)x移到320時(shí),y移動(dòng)到60故慈,算出沒移動(dòng)一點(diǎn)x板熊,移動(dòng)多少y
offsetY = offsetX * 60 / 320 手指每移動(dòng)一點(diǎn),x軸偏移量多少察绷,y偏移多少
為了好看干签,x移動(dòng)到320,距離上下的高度需要保持一致拆撼,而且有一定的比例去縮放他的尺寸容劳。
怎么根據(jù)之前的frame喘沿,算出當(dāng)前的frame,touchMove只能拿到之前的frame.
當(dāng)前的高度 = 之前的高度 * 這個(gè)比例
縮放比例:當(dāng)前的高度/之前的高度 (screenH - 2 * offsetY) / screenH
當(dāng)前的寬度也一樣求。
y值竭贩,計(jì)算比較特殊蚜印,不能直接用之前的y,加上offsetY,往左滑動(dòng),主視圖應(yīng)該往下走留量,但是offsetX是負(fù)數(shù)窄赋,導(dǎo)致主視圖會(huì)往上走。
y = (screenH - 當(dāng)前的高度)* 0.5
getCurrentFrameWithOffsetX - 定位(滑動(dòng)松開手指的時(shí)候楼熄,移動(dòng)到目標(biāo)點(diǎn))
移動(dòng)到左右目標(biāo)點(diǎn)忆绰,根據(jù)偏移量 = 當(dāng)前目標(biāo)點(diǎn)的x - 之前視圖的x,計(jì)算移動(dòng)到目標(biāo)點(diǎn)的frame
還原:當(dāng)沒有移動(dòng)到目標(biāo)點(diǎn)可岂,就把主視圖還原错敢。 - 復(fù)位(當(dāng)主視圖不在原始的位置结洼,點(diǎn)擊屏幕棋蚌,恢復(fù)原來位置)
判斷手指是否移動(dòng),移動(dòng)的時(shí)候就自動(dòng)定位袱院,不需要手動(dòng)復(fù)位平斩。
- 8> 手勢識(shí)別
使用UIImageView原因:之前既能看見圖片亚享,又能監(jiān)聽點(diǎn)擊的只有UIButton,學(xué)了手勢,我們的UIImageView也可以双戳。- tap(代理:左邊不能點(diǎn)虹蒋,右邊能點(diǎn))
- longPress(allowableMovement:觸發(fā)之前,最大的移動(dòng)范圍)
默認(rèn)調(diào)用兩次飒货,開始一次魄衅,結(jié)束一次。
* swipe:(一個(gè)手勢只能識(shí)別一個(gè)方向)
* 旋轉(zhuǎn):
基于上一次旋轉(zhuǎn)
注意:通過transform形變塘辅,需要去掉autolayout,才準(zhǔn)確
* 復(fù)位:(手勢的取值都是相對(duì)最原始的位置晃虫,我們應(yīng)該是需要相對(duì)上一次,因此每次調(diào)用扣墩,就復(fù)位一下哲银,每次都是從零開始旋轉(zhuǎn)角度)
縮放:復(fù)位
* 如何同時(shí)支持旋轉(zhuǎn)和縮放?默認(rèn)不支持多個(gè)手指呻惕,
Simultaneously:同時(shí)
當(dāng)使用一個(gè)手勢的時(shí)候會(huì)調(diào)用代理的Simultaneously方法荆责,詢問是否支持多個(gè)手勢
* pan
獲取平移的位置:translationInView
復(fù)位:setTranslation:inView: 需要傳一個(gè)view,因?yàn)辄c(diǎn)的位置跟坐標(biāo)系有關(guān)系亚脆,看他是基于哪個(gè)坐標(biāo)系被清空的做院。