iOS事件處理——Swift & Objective-C 表述

怎樣選擇最合適處理事件的控件

  • 當(dāng)用戶點(diǎn)擊屏幕后,產(chǎn)生2個(gè)參數(shù) 一個(gè)touches 保存用戶點(diǎn)擊的 UITouch對(duì)象到 NSSet 中,和一個(gè)事件對(duì)象UIEvent ,并且加入到UIApplication 對(duì)象的事件處理Loop中隊(duì)列

  • 由UIApplication查看,當(dāng)前有沒有堵塞,如果沒有就將事件分發(fā)下去,一般是交給主窗口,keyWindow

  • 然后Window 會(huì)用 下面的這個(gè)方法

 //Swift
func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? 

//Objective-C
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
 
  • 該方法是用于查詢當(dāng)前最佳處理事件的控件,如果我們重寫window的這個(gè)方法后,其他view的觸摸事件沒受影響,那么說(shuō)明我們的思路是對(duì)的,廢話不多說(shuō),代碼帶注釋

Swift

override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? {

        /*1.判斷自己可不可以與用戶交互滿足一下幾點(diǎn)
        1.self.userInteractionEnabled = YES 可以與用戶交互
        2.self.hidden = NO 不是隱藏的
        3.self.alpha > 0.01 透明度大于 0.01 也就是用戶可見
        */

        //下面是寫的上面的反面
        if self.userInteractionEnabled == false || self.hidden == true || self.alpha <= 0.01 {
            return nil
        }

        /*2.這里查看這個(gè)點(diǎn)是不是在控件的bound上了,如果不在就返回nil */

        if self.pointInside(point, withEvent: event) == false { return nil }


        /*3.遍歷 子控件,由于addSubView 本身是把圖層加到另
        一個(gè)圖層上面,導(dǎo)致圖層的順序是最后添加的在最上面,也就是
        上面說(shuō)的,后面加入的控件可能會(huì)在蓋住,前面加入的控件圖
        層,而響應(yīng)鏈?zhǔn)莾?yōu)先最上面的圖層的,考慮到這個(gè)遞歸算法是 
        DFS 也就是深度優(yōu)先,所以必須從后面的子控件遍歷
        */


        //3.1得到子控制總個(gè)數(shù)
        let count = Int(self.subviews.count) - 1


        for var i = count ; i >= 0 ; --i  {

            //1.得到子控件
            let childView:UIView = self.subviews[i]

            /*2,將父控件的坐標(biāo)點(diǎn)轉(zhuǎn)換到子控件中的形式,其實(shí)就拿
            子控件在父控件的frame的x,y ,與用戶觸點(diǎn)的父控件的
            x,y,進(jìn)行減法*/

            let childPoint = self.convertPoint(point, toView: childView)

            //3.繼續(xù)遞歸
            let firstView = childView.hitTest(childPoint, withEvent: event)

            //4.發(fā)現(xiàn)不為空,就回傳
            if let notEmpty = firstView {
                return notEmpty
            }
            
        }
        //5.如果沒知道合適的處理事件控件,就返回自己
        return self
        
    }
 
  • 上面說(shuō)的自己寫self.convertPoint(point, toView: childView)這方法,其實(shí)就是下面的算法
func myConvertPoint(point:CGPoint, toView view:UIView) -> CGPoint {

        //1.拿到子控件的x,y
        let x = view.frame.origin.x
        let y = view.frame.origin.y

        //2.進(jìn)行減法,并且返回
        return CGPointMake(point.x - x, point.y - y)

    }  

Objective-C

  • 這里我的另一種思路,但是不提倡
/*只要進(jìn)入了這個(gè)方法,那就代表了這個(gè)視圖,是可以與用戶交互,包含那個(gè)點(diǎn)的。
但是站在面向?qū)ο蟮慕嵌?,思考?wèn)題,”誰(shuí)最清楚,控件能否被點(diǎn)擊,
點(diǎn)在不在自己身上,當(dāng)然是自己",所以不提倡這樣的寫法*/
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
   
    int count = (int)self.subviews.count;

    for( int i = count - 1 ; i >= 0 ; --i ) {

        //1.拿到子控件
        UIView * childView = self.subviews[i];

        //2.轉(zhuǎn)換坐標(biāo)點(diǎn)
        CGPoint childPoint = [self convertPoint:point toView:childView];

        //3.判斷子控件能不能與用戶交互
        BOOL flagEnable = childView.userInteractionEnabled == YES || childView.hidden == NO || childView.alpha > 0.01;

        //4.判斷點(diǎn)在不在子控件上
        BOOL flagInside = [childView pointInside:childPoint withEvent:event];

        //5.如果都可以,那么繼續(xù)遞歸
        if (flagInside && flagEnable) {

            UIView *firstView = [childView hitTest:childPoint withEvent:event];
            //6.如果有,就回傳
            if (firstView) {
                return firstView;
            }
        }
    }

    //7.沒找到最合適的就返回自己
    return self;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文來(lái)自:http://ios.jobbole.com/84081/ 前言: 按照時(shí)間順序,事件的生命周期是這樣的...
    HackerOnce閱讀 2,940評(píng)論 1 10
  • 1、禁止手機(jī)睡眠[UIApplication sharedApplication].idleTimerDisabl...
    DingGa閱讀 1,199評(píng)論 1 6
  • UIView(控件) 功能一:界面顯示1. 屏幕上顯示的所有UI元素都叫做控件,也有人叫做視圖、組件;按鈕(UIB...
    翻這個(gè)墻閱讀 738評(píng)論 0 0
  • 還記得畢業(yè)之際 六月再見七月你好的人生感悟嗎? 還記得當(dāng)初升職加薪出任CEO迎娶白富美, 走上人生巔峰的小激動(dòng)是不...
    支招朱小斌閱讀 291評(píng)論 0 0
  • 中國(guó)人的價(jià)值觀念里有一句話叫好死不如賴活著。 在快節(jié)奏的社會(huì),我們不斷地抱怨。抱怨自己買不起名牌,找不到好工作,每...
    木錦萱閱讀 669評(píng)論 0 6

友情鏈接更多精彩內(nèi)容