讓超出父視圖范圍的子視圖響應事件,在UIView范圍外響應點擊


//重寫該方法后可以讓超出父視圖范圍的子視圖響應事件
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    UIView *view = [super hitTest:point withEvent:event];
    if (view == nil) {
        for (UIView *subView in self.subviews) {
            CGPoint tp = [subView convertPoint:point fromView:self];
            if (CGRectContainsPoint(subView.bounds, tp)) {
                view = subView;
            }
        }
    }
    return view;
}

 

如果一個button有一部分超出父控件的范圍了,這部分無法響應點擊,如果想讓它響應點擊應該怎么做

字數536 閱讀488 評論6

標題中的需求其實常常能遇到,如下圖


屏幕快照 2016-04-08 下午1.07.00.png

當按鈕超出Tab bar的view后,那么其實按鈕超出的部分是無法被點擊的。那么先來說說解決辦法

1.我們重寫藍色view的- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event的方法

  - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{ //if內的條件應該為,當觸摸點point超出藍色部分,但在黃色部分時 if (.....){ return YES; } return NO; }

那么以上為什么能解決方法?

這和iOS的事件分發機制 hit-Testing有關,簡單的說,hit-Testing的作用就是找出你每次觸摸屏幕,點到的究竟是哪個view。

比如以下這個圖


屏幕快照 2016-04-08 下午1.38.09.png

當我去點擊View-C的時候,hit-Testing實際上是這樣檢測的
1.首先,視圖會先從View-A開始檢查,發現觸摸點在View-A,所以檢查View-A的子視圖View-B。
2.發現觸摸點在View-B內,好棒!看看View-B內的子視圖View-C。
3.發現觸摸點在View-C內,但View-C沒有子視圖了,所以View-C是此次觸摸事件的hit-TestView了。

那么UIView中其實提供了兩個方法來確定hit-TestView
1.- (UIView )hitTest:(CGPoint)point withEvent:(UIEvent )event;
2.- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;//這個就是我們上面重寫的方法

注意其實在每次遞歸去調用hitTest:(CGPoint)point withEvent:(UIEvent *)event之前,都會調用pointInside:withEvent:來確定該觸摸點是否在該View內。

所以當我們重寫pointInside:(CGPoint)point withEvent:(UIEvent *)event后,其實我們的點擊后調用hitTest來遞歸的找hit-TestView的區域從這樣:

變成了這樣:

這樣當我們愉快的點擊上半凸起的區域時,hit-Testing便回去檢查藍色視圖內的子視圖,即黃色區域。從而來完成此次觸摸事件。
Enjoy :)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM