iOS7/8 UIButton高亮狀態延遲問題全解,ios7uibutton

來源:互聯網
上載者:User

iOS7/8 UIButton高亮狀態延遲問題全解,ios7uibutton

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

UIButton在某些情況下不能立刻響應TouchDown事件,換句話說,迅速點擊按鈕時,你是永遠看不見這個按鈕的高亮狀態的。

而你會發現,出現這種情況時,這些按鈕都在UIScrollView(UITableView)上。
為此我用了一下午時間查貼整理,得到了完美的解決方案。


在介紹解決方案前,必須先科普一些事實,協助大家理解:
UIScrollView:
1、屬性delaysContentTouches,布爾類型,預設值為YES。值為YES時,UIScrollView會在接收到手勢時延遲150ms來判斷該手勢是否能夠出發UIScrollView的滑動事件;值為NO時,UIScrollView會立馬將接收到的手勢分發到子視圖上。
(註:僅僅設定這個是不夠的,你會發現如果想要拖動scrollView而起點落在其他有手勢識別的視圖上時會拖不動)
2、方法- (BOOL)touchesShouldCancelInContentView:(UIView *)view,此方法的重載是協助我們完美解決問題的重點,決定手勢是否取消傳遞到view上,拖動ScrollView時觸發。返回NO時,拖動手勢將留在ScrollView上,返回YES則將手勢傳到view上。(若view是UIControl,則預設返回YES)


UITableView:
不得不說,UITableView(包括UITableViewCell在內)在iOS7和iOS8中的視圖結構是不同的,且存在著很多我們在編碼時永遠接觸不到的視圖,但我們可通過Debug將其subviews逐個逐個找出來。這關係到我們這個問題坑比較深的層次。
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屬性設定成為NO。
2、繼承UIScrollView或UITableView,並重寫- (BOOL)touchesShouldCancelInContentView:(UIView*)view方法,讓其響應拖動方法。


以下是參考代碼:
為了簡便我將兩個類的子類寫在同一個檔案中

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都能快速響應子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:方法中設定對應cell中的UITableViewCellScrollView。


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



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.