collectionviewcell 添加刪除按鈕 響應區域的問題

在collectionviewcell 的右上角添加了一個刪除按鈕,可是發現只有cell和刪除按鈕重合的區域纔會響應點擊事件 ide

 

 

後來doctor 李說這是iOS 事件響應鏈的機制(http://www.jianshu.com/p/d8512dff2b3e):button是cell的子view,只有父view響應了點擊事件後,子view才能夠響應,所以,ui

在cell的裏 添加一個方法:當子view超出父view的響應區域時,根據button的frame也響應spa

//刪除按鈕在cell區域外也響應事件
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    
    if(CGRectContainsPoint(self.bounds, point))
    {
        return YES;
    }else
    {
        if(CGRectContainsPoint(self.deleteBtn.frame ,point))
        {//若是是button區域的話,也響應
            return YES;
        }else{
            return NO;
        }
    }
}

 擴大按鈕的點擊區域:自定義button,重寫button的pointInSide方法,例如設計

@interface CloseBtn : UIButton

@end
@implementation CloseBtn

//擴大關閉按鈕的點擊區域,左右增長20
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    CGRect bounds = self.bounds;
    
    bounds = CGRectInset(bounds, -20, -20);
    return CGRectContainsPoint(bounds, point);
}


@end

更詳細的說明參考:http://www.jianshu.com/p/43c22fa3b42ccode

需求點


通常來講按鈕的點擊範圍和按鈕的大小是相等的,可是若是按鈕很小,就會形成難以點擊的狀況,甚至有的時候按鈕周圍還有別的可點擊區域,形成常常誤點擊的差體驗。視頻

實現方法


網上主要有幾種實現的方法:blog

  1. 設置按鈕的圖片setImage:,而後將按鈕的size設置得比圖片大。
  2. 在按鈕上面覆蓋一層較大透明的UIViewUIButton,設置點擊事件。

以上的方法自己侷限性仍是比較大的。第一條:若是按鈕沒有圖片怎麼辦?第二條:會改變視圖的層級。因此筆者歷來沒有試過。
筆者比較喜歡在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來具體作一下點擊範圍擴大和縮小的對比:

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類,重寫這個方法就能夠任意改變按鈕的可點擊區域,並且不依賴是否有圖片,也不改變視圖的層級。

相關文章
相關標籤/搜索