小Tip:最優雅擴大UIButton的可點擊范圍

問題

一般來說按鈕的點擊范圍和按鈕的大小是相等的,但是如果按鈕很小,就會造成難以點擊的情況,甚至有的時候按鈕周圍還有別的可點擊區域,造成經常誤點擊的差體驗。

一般實現方法

1、設置按鈕的圖片setImage:,然后將按鈕的size設置得比圖片大。
2、在按鈕上面覆蓋一層較大透明的UIView或UIButton,設置點擊事件。

以上兩個方法本身局限性還是比較大的:
1、如果按鈕沒有圖片怎么辦?
2、會改變視圖的層級。
不推薦、比較low。

推薦合理的方法

在WWDC 2012 Session 216視頻中提到的一種解決方式:通過重寫UIButton自身的 -(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event方法。

  - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event {

        //獲取當前button的實際大小
        CGRect bounds = self.bounds;

       //若原熱區小于44x44,則放大熱區,否則保持原大小不變
       CGFloat widthDelta = MAX(44.0 - bounds.size.width, 0);
       CGFloat heightDelta = MAX(44.0 - bounds.size.height, 0);

       //擴大bounds
       bounds = CGRectInset(bounds, -0.5 * widthDelta, -0.5 * heightDelta);
   
        //如果點擊的點在新的bounds里,就返回YES
       return CGRectContainsPoint(bounds, point);
   }

Apple的iOS人機交互設計指南中指出,按鈕點擊熱區應不小于44x44pt,否則這個按鈕就會讓用戶覺得“很難用”,所以在這段代碼里,以44為峰值,如果寬度,或高度小于44,就要擴大按鈕的區域,否則保持原有大小。

bounds = CGRectInset(bounds, -0.5 * widthDelta, -0.5 * heightDelta);

這段代碼應該就是改變bouds的代碼了。后兩個參數是指在左右方向和上下方向擴大或縮小的長度。正值為縮小,負值為擴大。

Demo

效果圖:


藍色:按鈕 | 綠色:可點擊范圍

圖中,上兩個藍色的正方形就是按鈕,一大一小。綠色的正方形是二者各自可點擊的區域。這里將第一個小按鈕的點擊范圍擴大了,將第二個大按鈕的點擊范圍縮小了。

那么如何得知按鈕點擊的范圍呢?

代碼分析:

第一個按鈕的重寫:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event{ 
    CGRect bounds = self.bounds;
    bounds = CGRectInset(bounds, -100, -100); 
    return CGRectContainsPoint(bounds, point);
}

該按鈕的點擊范圍上下左右同時擴大了100,因此,點擊范圍的寬度 = 按鈕的寬度 + 100*2;
因此,按鈕的寬度是30,那么點擊范圍的寬度就是230,而且顯然,二者的center應該是同一個。

同理
第二個按鈕的重寫:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent*)event {
    CGRect bounds = self.bounds; 
    bounds = CGRectInset(bounds, 20, 20); 
    return CGRectContainsPoint(bounds, point);
 }

第二個按鈕的寬度為100,那么它的可點擊寬度就被“縮”成了60(100 - 2*20)

為了演示方便,本Demo修改的是正方形按鈕的點擊范圍,而且點擊范圍在橫向和縱向的長度也都是一樣的。當然這種方法同樣可以適用于長方形,而且擴大或縮小的點擊范圍在橫向和縱向的長度也可以不一樣,可自行嘗試。

只要繼承UIButton類,重寫這個方法就可以任意改變按鈕的可點擊區域,而且不依賴是否有圖片,也不改變視圖的層級。

注:

通過修改bounds 的x,y 值就可以只向X 軸或者Y軸的某一個方向擴展

當bounds 的X 為0,Y 為負,就只向Y的正方向擴展點擊區域,反之亦然
當bounds 的Y 為0,X 為負,就只向X的正方向擴展點擊區域,反之亦然

如:

CGRect bounds = CGRectMake(0, -70, self.bounds.size.width, self.bounds.size.height);

參考:http://www.lxweimin.com/p/43c22fa3b42c

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 擴大點擊范圍的方法網上有很多 ,發現都不能滿足我的需求,我需要擴大按鈕的點擊區域是只向一個方向擴展點擊區域,向X軸...
    wg689閱讀 11,704評論 10 109
  • 重寫一個Button類,這個類繼承與UIButton,重寫 - (BOOL)pointInside:(CGPo...
    東了個尼閱讀 521評論 0 1
  • 今天天氣突然降溫,夜晚喝著冰鎮啤酒,看著窗外微涼的秋雨。感覺一切都太突然。我還賴在夏天不肯走,借一杯啤酒假裝在...
    Miss文小姐閱讀 194評論 2 0
  • 2017年09月1號 星期五 小雨(七月十一) 9月1號啦,經典而又值得期待的日子,熊孩子們結束...
    會飛的魚GLJ閱讀 247評論 0 0
  • 姓名:母光艷 公司:寧波貞觀電器 第235期,利他二組 【日精進打卡第84天】 【知-學習】 誦讀《六項精進》大綱...
    母光焱閱讀 115評論 0 0