標籤:
今天做一個九宮格密碼的項目,設button的selected狀態,怎麼都不對,後來發現這個屬性的作用
[btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
btn.userInteractionEnabled = NO;
//設定選中的圖片
[btn setBackgroundImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected];
如果要切換 button的selected的值 必須要設定這樣的屬性否則互動式作為 enabled 作為互動
屬性作用
該屬性值為布爾類型,如屬性本身的名稱所釋,該屬性決定UIView是否接受並響應使用者的互動。
當值設定為NO後,UIView會忽略那些原本應該發生在其自身的諸如touch和keyboard等使用者事件,並將這些事件從訊息佇列中移除出去。當值設定為YES後,這些使用者事件會正常的派發至UIView本身(前提事件確實發生在該view上),UIView會按照之前註冊的事件處理方法來響應這些事件。
在一次動畫執行流程中,動畫包含的所有UIView都會被臨時禁止使用者互動,而不管每個UIView本身userInteractionEnabled此時的屬性值是YES還是NO。但是在配置動畫時,通過添加UIViewAnimationOptionAllowUserInteraction選項可以禁止這種行為的發生,使UIView即使是在執行動畫期間依然能響應使用者事件。
發揮作用的簡單原理描述
熟悉IOS訊息響應鏈的開發人員都瞭解Hit-Testing的基本過程,此處對此不做深究,我們可以簡單的理解為在一次使用者的touch互動中,是hit-test決定了Application的整個view階層中,到底該由哪個view去接收並處理該事件。其基本的篩選過程可以粗糙的敘述為:
- touch事件發生,建立UIEvent對象
- 按照Application的view階層,逐層調用每個view的hitTest:withEvent:方法,並傳入該event對象,view根據hitTest:withEvent:方法和來決定touch點是否包含在自己的bounds中;
- 如果view的bounds包含了touch點,該view會遍曆自己的subview,並調用每個subview的pointInside:withEvent:方法來進一步決定touch事件是發生在自己本身,還是自己的subview上。
- 重複第二,三步,並篩選出最終接受touch事件的view對象
我們關注的是篩選過程的第3步,view調用hitTest:withEvent:方法時,會受userInteractionEnabled屬性設定的影響,如果當view的該屬性值設定為NO時,即使最終touch點確實包含在view的bounds中,該view也會忽略touch事件,當然userInteractionEnabled的設定只是touch篩選的條件之一,在真正的篩選過程中還包含了其他因素的考慮,因此還要參考hitTest:withEvent:的具體方法描述,但以上描述個人感覺足夠我們理解userInteractionEnabled屬性的基本原理。
特殊子類的覆蓋
userInteractionEnabled屬性預設值為YES,但UIView的一些子類中對該屬性進行了覆蓋,並將其預設值設定為了NO,其中UIImageView和UILabel就是這樣的類。userInteractionEnabled屬性在UIImageView和UILabel的文檔中都有簡單的描述。在實際的介面開發過程中,我們經常用UIImageView來類比按鈕或其它可以響應使用者touch事件的顯示區,並通過gesture來為其添加事件響應,因此為了保證事件能正常的接受,我們必須要顯示的將UIImageView對象的userInteractionEnabled的值設為YES 。
iOS bug 日誌-userInteractionEnabled