響應鏈的構成
app中,視圖都是按照樹狀結構組織起來的赞哗,構成樹狀結構的同時也構成了響應鏈雷则。
找到第一響應者的過程
用戶觸發(fā)某一事件后,UIKIt生成一個UIEvent對象肪笋,該對象包含一些處理事件所需信息月劈。處理事件時度迂,UIApplication對象把事件分發(fā)給window對象,window對象分發(fā)給事件發(fā)生的VC視圖上艺栈,視圖按照觸摸的位置遞歸檢測其所有子視圖英岭,包含觸摸點的最底層視圖就是hit-testing視圖。系統(tǒng)將事件發(fā)送給這個視圖處理湿右,然后就是視圖響應鏈的過程
響應鏈的響應過程
1.觸發(fā)了一個事件诅妹,app首先按照樹狀結構找到第一響應者(通過hit-test方式)
2.如果第一響應者不能處理事件,傳遞給他的父視圖毅人,一直循環(huán)到viewController
3.如果viewController無法處理吭狡,傳遞給window對象
4.如果window對象無法處理,傳遞給UIApplication對象處理丈莺,如果還是無法處理划煮,丟棄事件
如果父視圖有如上設置
view.hidden=YES;
view.alpha = 0.0f;
view.userInteractionEnabled = NO;
則子視圖不能接受觸摸事件,包括攔截操作
攔截響應者鏈
需要攔截響應者對象的View重寫
- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event;方法
方法1缔俄,返回需要響應的視圖(推薦)
方法2弛秋,返回自己,但是因為尋找響應者的過程是后添加的視圖先檢查俐载,所以有可能沒遍歷到自己就找到了真正響應的view蟹略,攔截失敗
管理響應者鏈
Returns the next responder in the responder chain, or nil
if there is no next responder.
The UIResponder
class does not store or set the next responder automatically, so this method returns nil
by default. Subclasses must override this method and return an appropriate next responder. For example, UIView
implements this method and returns the UIViewController object that manages it (if it has one) or its superview (if it doesn’t). UIViewController similarly implements the method and returns its view’s superview. UIWindow
returns the application object. UIApplication
returns nil
Returns
The next object in the responder chain or nil
if this is the last object in the chain.
- (nullable UIResponder*)nextResponder;
//Tells this object when a physical button is first pressed.
UIKit calls this method when a new button is pressed by the user. Use this method to determine which button was pressed and to take any needed actions.
The default implementation of this method forwards the message up the responder chain. When creating your own subclasses, call super
to forward any events that you do not handle yourself.
Parameters
presses
A set of UIPress instances that represent the new presses that occurred. The phase of each press is set to UIPressPhaseBegan.
event
The event to which the presses belong.
//物理設備回調(diào),UIPress對象告訴你哪個按鈕被按了
- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event ;
//接收到遠程設備命令時調(diào)用遏佣,為了允許分發(fā)遠程控制事件挖炬,我們必須調(diào)用UIApplication的beginReceivingRemoteControlEvents方法;而如果要關閉遠程控制事件的分發(fā)状婶,則調(diào)用endReceivingRemoteControlEvents方法意敛。
- (void)remoteControlReceivedWithEvent:(nullable UIEvent *)event NS_AVAILABLE_IOS(4_0);
//驗證命令,啟用或禁用指定的命令
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
//
- (nullable id)targetForAction:(SEL)action withSender:(nullable id)sender
輸入視圖
@property (nullable, nonatomic, readonly, strong) __kindof UIView *inputView NS_AVAILABLE_IOS(3_2);
@property (nullable, nonatomic, readonly, strong) __kindof UIView *inputAccessoryView NS_AVAILABLE_IOS(3_2);
當對象變?yōu)榈谝豁憫邥r膛虫,顯示另外的視圖用來處理信息輸入草姻,比如UITextField,UITextView的鍵盤稍刀,自定義鍵盤就是用自定義的view替換
//視圖立即被替換
-(void)reloadInputViews
獲取undoManager
可以用來執(zhí)行對應視圖的undo和redo操作
http://www.th7.cn/Program/IOS/201603/774913.shtml
http://southpeak.github.io/2015/03/07/cocoa-uikit-uiresponder/