小Tip:最優(yōu)雅擴(kuò)大UIButton的可點(diǎn)擊范圍

問題

一般來說按鈕的點(diǎn)擊范圍和按鈕的大小是相等的,但是如果按鈕很小,就會造成難以點(diǎn)擊的情況父晶,甚至有的時候按鈕周圍還有別的可點(diǎn)擊區(qū)域,造成經(jīng)常誤點(diǎn)擊的差體驗(yàn)弄跌。

一般實(shí)現(xiàn)方法

1甲喝、設(shè)置按鈕的圖片setImage:,然后將按鈕的size設(shè)置得比圖片大铛只。
2埠胖、在按鈕上面覆蓋一層較大透明的UIView或UIButton,設(shè)置點(diǎn)擊事件淳玩。

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

推薦合理的方法

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

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

        //獲取當(dāng)前button的實(shí)際大小
        CGRect bounds = self.bounds;

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

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

Apple的iOS人機(jī)交互設(shè)計指南中指出铁蹈,按鈕點(diǎn)擊熱區(qū)應(yīng)不小于44x44pt宽闲,否則這個按鈕就會讓用戶覺得“很難用”众眨,所以在這段代碼里,以44為峰值容诬,如果寬度娩梨,或高度小于44,就要擴(kuò)大按鈕的區(qū)域览徒,否則保持原有大小狈定。

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

這段代碼應(yīng)該就是改變bouds的代碼了。后兩個參數(shù)是指在左右方向和上下方向擴(kuò)大或縮小的長度习蓬。正值為縮小纽什,負(fù)值為擴(kuò)大。

Demo

效果圖:


藍(lán)色:按鈕 | 綠色:可點(diǎn)擊范圍

圖中躲叼,上兩個藍(lán)色的正方形就是按鈕芦缰,一大一小。綠色的正方形是二者各自可點(diǎn)擊的區(qū)域枫慷。這里將第一個小按鈕的點(diǎn)擊范圍擴(kuò)大了让蕾,將第二個大按鈕的點(diǎn)擊范圍縮小了。

那么如何得知按鈕點(diǎn)擊的范圍呢或听?

代碼分析:

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

該按鈕的點(diǎn)擊范圍上下左右同時擴(kuò)大了100探孝,因此,點(diǎn)擊范圍的寬度 = 按鈕的寬度 + 100*2;
因此誉裆,按鈕的寬度是30顿颅,那么點(diǎn)擊范圍的寬度就是230,而且顯然找御,二者的center應(yīng)該是同一個元镀。

同理
第二個按鈕的重寫:

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

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

為了演示方便栖疑,本Demo修改的是正方形按鈕的點(diǎn)擊范圍,而且點(diǎn)擊范圍在橫向和縱向的長度也都是一樣的滔驶。當(dāng)然這種方法同樣可以適用于長方形遇革,而且擴(kuò)大或縮小的點(diǎn)擊范圍在橫向和縱向的長度也可以不一樣,可自行嘗試揭糕。

只要繼承UIButton類萝快,重寫這個方法就可以任意改變按鈕的可點(diǎn)擊區(qū)域,而且不依賴是否有圖片著角,也不改變視圖的層級揪漩。

注:

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

當(dāng)bounds 的X 為0吏口,Y 為負(fù)奄容,就只向Y的正方向擴(kuò)展點(diǎn)擊區(qū)域冰更,反之亦然
當(dāng)bounds 的Y 為0,X 為負(fù)昂勒,就只向X的正方向擴(kuò)展點(diǎn)擊區(qū)域蜀细,反之亦然

如:

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

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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市戈盈,隨后出現(xiàn)的幾起案子奠衔,更是在濱河造成了極大的恐慌,老刑警劉巖塘娶,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件归斤,死亡現(xiàn)場離奇詭異,居然都是意外死亡刁岸,警方通過查閱死者的電腦和手機(jī)官册,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來难捌,“玉大人膝宁,你說我怎么就攤上這事「酰” “怎么了员淫?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長击敌。 經(jīng)常有香客問我介返,道長,這世上最難降的妖魔是什么沃斤? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任圣蝎,我火速辦了婚禮,結(jié)果婚禮上衡瓶,老公的妹妹穿的比我還像新娘徘公。我一直安慰自己,他們只是感情好哮针,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布关面。 她就那樣靜靜地躺著,像睡著了一般十厢。 火紅的嫁衣襯著肌膚如雪等太。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天蛮放,我揣著相機(jī)與錄音缩抡,去河邊找鬼。 笑死包颁,一個胖子當(dāng)著我的面吹牛瞻想,可吹牛的內(nèi)容都是我干的挎塌。 我是一名探鬼主播,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼内边,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了待锈?” 一聲冷哼從身側(cè)響起漠其,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎竿音,沒想到半個月后和屎,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡春瞬,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年柴信,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宽气。...
    茶點(diǎn)故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡随常,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出萄涯,到底是詐尸還是另有隱情绪氛,我是刑警寧澤,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布涝影,位于F島的核電站枣察,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏燃逻。R本人自食惡果不足惜序目,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望伯襟。 院中可真熱鬧猿涨,春花似錦、人聲如沸姆怪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽片效。三九已至红伦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間淀衣,已是汗流浹背昙读。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留膨桥,地道東北人蛮浑。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓唠叛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親沮稚。 傳聞我的和親對象是個殘疾皇子艺沼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容

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