UI篇-自定義控制元件之基類UIControl

weixin_34389926發表於2018-01-17
1755386-2c93ca9f775fa196.jpeg

UIControl的意義所在

UIControl的主要角色是定義一套介面和基礎實現,為iOS的人機互動制定了一系列的標準,
為了當確定的事件發生的時候(比如點選了按鈕)準備好動作訊息(Action)並開始派發它們到自己的目標(Target,eg:UIViewController)。

UIControl是控制元件的基類,不能直接的例項化,它只能通過繼承的方式為子類提供公共的介面和動作結構。

UIControl事件實現原理

  • 比如我們有一個按鈕,當他點選時候,我們執行ViewContollr的-(void)click:(id)sender方法,
  • 這裡傳入的UIControlEventTouchUpInside列舉量,就是在控制元件frame內按下,然後抬起這樣一個事件,
  • UIContol將這個事件作為key,和目標(target)和目標方法(action)存到了自己私有的字典裡。
  • 當使用者點選按鈕時,UIControl響應了觸控鏈的touchesEnded方法,便會根據私有字典,把對應UIControlEventTouchUpInside的目標(target)和目標方法(action)呼叫,這樣完成事件的回傳。

自定義控制元件可以怎樣實現

  • 繼承自UIView,這是大多數開發者的做法。也能夠實現需求,但是一個可互動控制元件,理應繼承於UIControl而非UIView。

  • 繼承自UIControl,使用UIControl的一套介面規範來實現自定義。

UIControl的重要方法

Target模式就是從UIControl使用的。

  • 準備併傳送動作訊息
    sendAction:to:forEvent:

     響應給定的事件,轉發一個動作訊息給應用程式派發給目標。
    - (void)sendAction:(SEL)`action`     to:(id)`target`       forEvent:(UIEvent*)`event`
    
     UIControl通過轉發一個目標動作給單例UIApplication(在它的sendAction:to:fromSender:forEvent:方法中)來實現這個方法來派發給它的目標,
      或者如果它沒有確定的目標,派發給響應鏈中第一個願意處理這個訊息的物件中。
      子類可能要過載這個方法來觀察或者修改動作轉發的行為。
      每進行一次指定控制元件的事件,可能會重複用sendActionsForControlEvents這個方法的實現,
    
  • 傳送動作訊息到給定的控制事件
    sendActionsForControlEvents

    - (void)sendActionsForControlEvents:(UIControlEvents *)controlEvents`
    UIControl實現這個方法來傳送所有controlEvents的動作訊息,在程式中重複呼叫,
    查詢目標和動作列表在`addTarget:action:forControlEvents:`.之前構造。
    
  • 在內部的派發表中給特殊時間新增一個目標和動作
    addTarget:action:forControlEvents:

      - (void)addTarget:(id)`target`      action:(SEL)`action` forControlEvents:(UIControlEvents)`controlEvents`
    你可能會多次呼叫這個方法,並且你可能需要為一個特殊的事件識別多個目標-動作組,
    動作訊息可以是可選的包含傳送者和事件作為引數
    當你呼叫這個方法的時候,目標沒有被保留。
    
  • 在內部派發表中將特定事件的目標和動作移除
    removeTarget:action:forControlEvents:

  • 返回所有跟動作事件和特殊指定控制事件相關的動作
    actionsForTarget:forControlEvent:

    - (NSArray *)actionsForTarget:(id)`target`   forControlEvent:( UIControlEvents)`controlEvent`
    一個包含NSString型別的方法名字的陣列或者沒有與控制事件相關的方法則則為nil
    
  • 返回與接受者相關聯的所有目標物件

    - (NSSet*)allTargets
     集合裡面的目標是動作訊息的接受者,
    
  • 返回與接受者相關聯的所有控制事件

    - (UIControlEvents )allControlEvents
    一個或者多個`UIControlEvents` 常量指定與當前接受者相關聯的的控制事件
    

UIControlEvents列舉,定義了iOS互動中的互動方式

UIControlEventTouchDown    控制元件被按下去的事件
UIControlEventTouchDownRepeat  控制元件被重複點選的時間,點選次數超過一次
UIControlEventTouchDragInside  在控制元件範圍內按下並拖動的事件
UIControlEventTouchDragOutside  在控制元件範圍內按下並在控制元件外面拖動的事件
UIControlEventTouchDragEnter  從控制元件範圍外拖動到控制元件範圍內的事件
UIControlEventTouchDragExit  從控制元件範圍外拖動到控制元件範圍內的事件
UIControlEventTouchUpInside  點選控制元件後在控制元件範圍內釋放觸發事件
UIControlEventTouchUpOutside  點選控制元件後在控制元件範圍外釋放觸發事件
UIControlEventTouchCancel  觸控取消事件
UIControlEventValueChanged  當控制元件的值發生改變時,傳送通知。用於滑塊,分段控制元件,以及其他取值控制元件。
UIControlEventEditingDidBegin  文字控制元件開始編輯時傳送通知
UIControlEventEditingChanged  文字控制元件中的內容被改變是傳送通知
UIControlEventEditingDidEnd  文字控制元件結束編輯的時候傳送通知
UIControlEventEditingDidEndOnExit  文字控制元件內通過按下回車(或等價行為)結束編輯時,傳送通知。
UIControlEventAllTouchEvents  通知所有觸控事件
UIControlEventAllEditingEvents  通知所有關於文字編輯的時間。
UIControlEventApplicationReserved  為應用程式預留
UIControlEventSystemReserved  為系統內部框架預留
UIControlEventAllEvents  通知所有事件

UIControlState定義了控制元件的基本狀態

typedef NS_OPTIONS(NSUInteger, UIControlState) {
UIControlStateNormal       = 0,
UIControlStateHighlighted  = 1 << 0,                  // used when UIControl isHighlighted is set
UIControlStateDisabled     = 1 << 1,
UIControlStateSelected     = 1 << 2,                  // flag usable by app (see below)
UIControlStateFocused NS_ENUM_AVAILABLE_IOS(9_0) = 1 << 3, // Applicable only when the screen supports focus
UIControlStateApplication  = 0x00FF0000,              // additional flags available for application use
UIControlStateReserved     = 0xFF000000               // flags reserved for internal framework use
};

相關文章