功能需求:當button超出父控件frame的時候如何與用戶交互
如圖:btn1和btn2都是藍色View的子控件,但是他們超出了藍色View的frame
如果不做任何處理,點擊btn,btn是不能與用戶交互的
Btn3在父控件范圍內,可以與用戶交互
這里是源碼
響應者鏈條:(系統如何找到最合適的View來響應用戶的交互)
當用戶點擊屏幕
產生一個點擊事件交給UIAppliction
UIAppliction交給UIWiondw
UIWiondw問控制器View:觸點在不在你身上?
在,則把點擊事件交給控制器View
控制器View問自己的子控件(從最后添加的,也就是最上層的view開始詢問):觸點在不在你身上?
在,則把事件傳遞給這個子View
不在,則繼續問下一個子控件
如果找到了合適的子控件,則把事件傳遞給子控件(子控件繼續詢問自己的子控件來查找更合適的view)
如果沒有找到,則自己處理事件
例如點擊了Btn3:
UIWiondw問控制器的白色View觸點在你身上嗎?
在,事件傳遞到控制器的白色View上
白色Viwe問藍色Viwe,觸點在你身上嗎?
在,事件傳遞到藍色View
然后藍色View問Btn3,觸點在你身上嗎?
在,則事件交給Btn3
Btn3已經沒有子控件(也就是沒有更合適的View了)
Btn3處理了點擊事件
又例如點擊了Btn1
UIWiondw問控制器的白色View觸點在你身上嗎?
在,事件傳遞到控制器的白色View上
白色Viwe問藍色Viwe,觸點在你身上嗎?
不在,則白色View處理點擊事件(因為白色View已經沒有其他子控件可以詢問,Btn1是藍色Viwe的子控件)
所以Btn1不能響應用戶的交互
如何讓Btn1與用戶交互
在詢問子View的時候,系統是通過這個方法來尋找最合適的View:
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
所以我們可以重寫控制器View的這個方法,來按照自己制定的規則來尋找最合適的View:
-(UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
//當前觸點坐標系是控制器的view
//轉換成btn1的坐標系
CGPoint btnP = [self convertPoint:point toView:self.btn1];
if ([self.btn1pointInside:btnP withEvent:event]) {//判斷點擊點是否在btn1上
//如果點擊點在btn1上 那么就讓btn1來處理事件
return self.btn1;
}else{
//如果不在btn1上 就按照系統默認做法 尋找合適的view來處理事件
return [super hitTest:point withEvent:event]
}
}
這樣的話,當觸點在Btn1上的時候,這個方法就會返回Btn1
那么系統就會把Btn1當做最合適的View來處理事件
感謝閱讀
你的支持是我寫作的唯一動力