iOS7/8 UIButton高亮狀態(tài)延遲問題全解

估計很多碼友都遇到過這樣的情況:

UIButton在某些情況下不能立刻響應(yīng)TouchDown事件,換句話說避乏,迅速點擊按鈕時,你是永遠看不見這個按鈕的高亮狀態(tài)的汗捡。

而你會發(fā)現(xiàn)淑际,出現(xiàn)這種情況時畏纲,這些按鈕都在UIScrollView(UITableView)上扇住。
為此我用了一下午時間查貼整理,得到了完美的解決方案盗胀。

在介紹解決方案前艘蹋,必須先科普一些事實,幫助大家理解:
UIScrollView:
1票灰、屬性delaysContentTouches女阀,布爾類型,默認值為YES屑迂。值為YES時浸策,UIScrollView會在接收到手勢時延遲150ms來判斷該手勢是否能夠出發(fā)UIScrollView的滑動事件;值為NO時惹盼,UIScrollView會立馬將接收到的手勢分發(fā)到子視圖上庸汗。
(注:僅僅設(shè)置這個是不夠的,你會發(fā)現(xiàn)如果想要拖動scrollView而起點落在其他有手勢識別的視圖上時會拖不動)
2手报、方法- (BOOL)touchesShouldCancelInContentView:(UIView *)view蚯舱,此方法的重載是幫助我們完美解決問題的重點,決定手勢是否取消傳遞到view上掩蛤,拖動ScrollView時觸發(fā)枉昏。返回NO時,拖動手勢將留在ScrollView上揍鸟,返回YES則將手勢傳到view上兄裂。(若view是UIControl,則默認返回YES)

UITableView:
不得不說,UITableView(包括UITableViewCell在內(nèi))在iOS7和iOS8中的視圖結(jié)構(gòu)是不同的懦窘,且存在著很多我們在編碼時永遠接觸不到的視圖前翎,但我們可通過Debug將其subviews逐個逐個找出來。這關(guān)系到我們這個問題坑比較深的層次畅涂。
iOS7:UITableView中存在n+1個UIScrollView港华,一個是UITableView本身,另外n個存在于UITableViewCell與cell的contentView之間午衰,類名為UITableViewCellScrollView立宜,活的不久,僅存在于iOS7中臊岸,在iOS8中已被移除橙数。
iOS8:UITableView中存在2個UIScrollView,一個是UITableView本身帅戒,另外一個存在于UITableView與UITableViewCell之間灯帮,類名為UITableViewWrapperView。需要注意的是逻住,UITableViewWrapperView在iOS7中并不是一個UIScrollView钟哥。

科普知識完,那么我們就有了以下的問題解決方案了:
1瞎访、將UIButton所有屬于UIScrollView的父視圖的delaysContentTouches屬性設(shè)置成為NO腻贰。
2、繼承UIScrollView或UITableView扒秸,并重寫- (BOOL)touchesShouldCancelInContentView:(UIView*)view方法播演,讓其響應(yīng)拖動方法。

以下是參考代碼:
為了簡便我將兩個類的子類寫在同一個文件中
NoDelayButtonScrollView.h:

import <UIKit/UIKit.h> @interface NoDelayButtonScrollView : UIScrollView @end @interface NoDelayButtonTableView : UITableView @end

NoDelayButtonScrollView.m(1):

import "NoDelayButtonScrollView.h" @implementation NoDelayButtonScrollView - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { self.delaysContentTouches = NO; } return self; } - (BOOL)touchesShouldCancelInContentView:(UIView *)view { if ([view isKindOfClass:[UIButton class]]) { return YES; } return [super touchesShouldCancelInContentView:view]; } @end

NoDelayButtonScrollView.m(2):

@implementation NoDelayButtonTableView - (id)initWithCoder:(NSCoder *)aDecoder { self = [super initWithCoder:aDecoder]; if (self) { self.delaysContentTouches = NO; // iterate over all the UITableView's subviews for (id view in self.subviews) { // looking for a UITableViewWrapperView if ([NSStringFromClass([view class]) isEqualToString:@"UITableViewWrapperView"]) { // this test is necessary for safety and because a "UITableViewWrapperView" is NOT a UIScrollView in iOS7 if([view isKindOfClass:[UIScrollView class]]) { // turn OFF delaysContentTouches in the hidden subview UIScrollView *scroll = (UIScrollView *) view; scroll.delaysContentTouches = NO; } break; } } } return self; } - (BOOL)touchesShouldCancelInContentView:(UIView *)view { if ([view isKindOfClass:[UIButton class]]) { return YES; } return [super touchesShouldCancelInContentView:view]; } @end
以上分別對UIScrollView和UITableView進行繼承伴奥,重寫initWithCoder:方法可保證使用Nib文件也能生效
使用這兩個類繼承寫出來的ScrollView和TableView都能快速響應(yīng)子Button的TouchDown事件写烤,并顯示高亮
但以上代碼仍未能解決iOS7下UITableView的子Button高亮延遲問題。

可加入以下代碼來解決:

for (id obj in cell.subviews) { if ([NSStringFromClass([obj class]) isEqualToString:@"UITableViewCellScrollView"]) { UIScrollView *scroll = (UIScrollView *) obj; scroll.delaysContentTouches = NO; break; } }
這段代碼可加在Custom的UITableViewCell的initWithCoder:方法中拾徙,也可以放在UITableViewDelegate的cellForRowAtIndexPath:方法中設(shè)置對應(yīng)cell中的UITableViewCellScrollView洲炊。

以上,是所有幫助你解決Button延遲高亮問題的方法锣吼。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末选浑,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子玄叠,更是在濱河造成了極大的恐慌古徒,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件读恃,死亡現(xiàn)場離奇詭異隧膘,居然都是意外死亡代态,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門疹吃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來蹦疑,“玉大人,你說我怎么就攤上這事萨驶∏复荩” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵腔呜,是天一觀的道長叁温。 經(jīng)常有香客問我,道長核畴,這世上最難降的妖魔是什么膝但? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮谤草,結(jié)果婚禮上跟束,老公的妹妹穿的比我還像新娘。我一直安慰自己丑孩,他們只是感情好冀宴,可當我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嚎杨,像睡著了一般花鹅。 火紅的嫁衣襯著肌膚如雪氧腰。 梳的紋絲不亂的頭發(fā)上枫浙,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天,我揣著相機與錄音古拴,去河邊找鬼箩帚。 笑死,一個胖子當著我的面吹牛黄痪,可吹牛的內(nèi)容都是我干的紧帕。 我是一名探鬼主播,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼桅打,長吁一口氣:“原來是場噩夢啊……” “哼是嗜!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起挺尾,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤鹅搪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后遭铺,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丽柿,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡恢准,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了甫题。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馁筐。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖坠非,靈堂內(nèi)的尸體忽然破棺而出敏沉,到底是詐尸還是另有隱情,我是刑警寧澤炎码,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布赦抖,位于F島的核電站,受9級特大地震影響辅肾,放射性物質(zhì)發(fā)生泄漏队萤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一矫钓、第九天 我趴在偏房一處隱蔽的房頂上張望要尔。 院中可真熱鬧,春花似錦新娜、人聲如沸赵辕。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽还惠。三九已至,卻和暖如春私杜,著一層夾襖步出監(jiān)牢的瞬間蚕键,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工衰粹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留锣光,地道東北人。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓铝耻,卻偏偏與公主長得像誊爹,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子瓢捉,可洞房花燭夜當晚...
    茶點故事閱讀 44,871評論 2 354

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