iOS 【UIKit-事件產生與傳送 練習(重寫hitTest和pointInside方法)】
阿新 • • 發佈:2019-02-17
練習要求:
在下圖中點選到綠色Button區域,Button響應(包括YellowView覆蓋的綠色Button部分也是由綠色Button來響應)。點選YellowView部分(除覆蓋綠色Button外的),YellowView響應。
解決思路:
如果我們只是一味的和之前一樣重寫綠色Button的hitTest方法,是不能很好的區分YellowView與綠色Button的重合部分的,他會讓點選的所有地方都是由綠色Button來響應。顯然和我們的想法有了偏離。
那麼我們應該在hitTest方法(YellowView中的hitTest方法)的重寫中判斷一下,如果點恰好也在綠色Button上,那麼我們就可以讓YellowView不響應這個事件,那麼編譯器就會接著往下遍歷綠色Button,然後讓綠色Button去響應。當然這裡重寫的hitTest方法是重寫YellowView中的,多體會幾次就可以理解了。
程式碼:
#import "YellowView.h" @implementation YellowView // 輸出響應者 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { NSLog(@"%s",__func__); } - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { // 將point轉化成為Button座標系上的點 CGPoint buttonPoint = [self convertPoint:point toView:_button]; // 如果點在綠色Button上,那麼返回nil,也就是YellowView退出遍歷了,不讓YellowView作為響應者 if ([_button pointInside:buttonPoint withEvent:event]) { return nil; } // 當然如果點不在綠色Button上,那麼就接著原來的hitTest方法執行,執行super語句。 return [super hitTest:point withEvent:event]; } @end
當然除了重寫hitTest方法可以實現這個功能,我們也可以重寫pointInside方法。
程式碼:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { // 這裡的呼叫者是self,因為point是當前view中的點 CGPoint buttonPoint = [self convertPoint:point toView:_button]; // 需要注意這裡的呼叫者是_button,因為這裡的point是buttonPoint也就是綠色Button中的點 if ([_button pointInside:buttonPoint withEvent:event]) { return nil; } return [super pointInside:point withEvent:event]; }
只需要將上面重寫hitTest方法的地方替換下來就好了。原理都是一樣的。