1. 程式人生 > >Button控制元件位置超出父檢視,點選無響應的解決辦法

Button控制元件位置超出父檢視,點選無響應的解決辦法

在日常開發中我們經常和按鈕打交道,但是有時候會碰到比較難處理的問題,就是按鈕不響應點選事件,這時候我們需要從下面幾方面排查。

按鈕不響應的原因

  • 1、按鈕新增到了一個沒有開啟使用者互動的父View上,例如UIImageView,這時候開啟父試圖的互動 view.userInteractionEnabled = YES
    設為YES就可以解決問題

  • 2、按鈕自身被遮擋,點選的時候根本就沒有點選到button,而是他上面一層View,自然就不會響應
    這裡有個看圖層的方法,下圖點選那個紅框的按鈕就可以看到當前執行介面的UI元素,你可以看到有沒有view遮擋住button

    · 3、按鈕的frame超出了父檢視的frame,這個是最容易出現的,按鈕的freme必須在父檢視的frame內部點選才有效,如下圖,按鈕點選紅框裡的區域是不響應的。
如果碰到這個問題怎麼辦呢,請繼續往下看

    

解決超出點選區域的問題

這種情況其實很有可能發生,舉個我碰到的栗子:聊天區域的高度小於鍵盤的高度,而輸入框是聊天區域的子View,在鍵盤彈出後,輸入框上移,而且超出了父檢視的frame,這個時候點選紅框的按鈕切換表情鍵盤動作就不響應。

解決辦法

這裡有兩個方法,每次有touch動作時,都會走這兩個方法

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event;
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event;

重寫方法 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event


這是View裡的一個方法,處理流程如下

  • 首先呼叫當前檢視的pointInside:withEvent:方法判斷觸控點是否在當前檢視內;
    若返回NO,則hitTest:withEvent:返回nil;
    若返回YES,則向當前檢視的所有子檢視(subviews)傳送hitTest:withEvent:訊息,所有子檢視的遍歷順序是從top到bottom,即從subviews陣列的末尾向前遍歷,直到有子檢視返回非空物件或者全部子檢視遍歷完畢;

  • 若第一次有子檢視返回非空物件,則hitTest:withEvent:方法返回此物件,處理結束;

  • 如所有子檢視都返回非,則hitTest:withEvent:方法返回自身(self)。

  • 最後,這個觸控事件交給主視窗的hitTest:withEvent:方法返回的檢視物件去處理。

所以我們可以在返回nil時進行處理,因為這個時候button是在父View外的

//返回一個view來響應事件
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    UIView *view = [super hitTest:point withEvent:event];
    if (view == nil){
        //轉換座標
        CGPoint tempPoint = [self.testBtn convertPoint:point fromView:self];
       //判斷點選的點是否在按鈕區域內
        if (CGRectContainsPoint(self.testBtn.bounds, tempPoint)){
            //返回按鈕
            return _testBtn;
        }
    }
    return view;
}

這個時候按鈕在區域外點選也有效果了

參考

作者:calary
連結:https://www.jianshu.com/p/7a35d6c25bfe
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。

------------------------------隔斷:URL編碼,解碼方法:

1.URL編碼

NSString *encodeURL = [url stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

2.URL解碼

NSString *decodeURL = [url stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

ios 9.0中已經替換此方法

NSString *encodedURL = [url stringByAddingPercentEncodingWithAllowedCharacters:(nonnull NSCharacterSet *)];

NSString *decodedURL = [url stringByRemovingPercentEncoding];