UITableView或UIScrollVIew上的UIButton的高亮效果,uibutton高亮效果
UITableView或UIScrollVIew上的UIButton的高亮效果
原文地址:http://www.jianshu.com/p/b4331f06bd34
最近做項目的時候發現,UIScrollView上的UIButton點擊的時候沒有高亮狀態,但是確實觸發了點擊事件,不過這樣會造成一個假象,給使用者看來UIButton沒有被點擊的感覺。 但是要是長時間點擊的話,則會高亮。於是我發現,導致這種現象應該就是時間長短的問題。順著這個問題想下去,就追尋到UIScrollView的touch原理,UIScrollView有一個delaysContentTouches的屬性。
蘋果官方的文檔解釋:default is YES. if NO, we immediately call -touchesShouldBegin:withEvent:inContentView:. this has no effect on presses
很明顯,delaysContentTouches 預設值為YES,即UIScrollView會在接受到手勢是延遲150ms來判斷該手勢是否能觸發UIScrollView的滑動事件;反之值為NO時,UIScrollView會立馬將接受到的手勢分發到子視圖上。
當然,delaysContentTouches設定為NO是遠遠不夠的,因為這樣的話你想要拖動UIScrollView而七點落在替他有手勢識別的視圖上是會拖不動的。 於是我們要重載touchesShouldCancelInContentView,此方法決定手勢是否取消傳遞到View上,拖動UIScrollView是觸發。返回NO時,拖動手勢將留在UIScrollView上;返回YES時,則傳到View上。
現在,方案就很明確了,我們只要將UIButton所有屬於UIScrollView的父視圖的delaysContentTouches屬性設定成為NO且重寫touchesShouldCancelInContentView方法就行。下面直接貼代碼
- (instancetype)initWithCoder:(NSCoder *)aDecoder {self = [super initWithCoder:aDecoder];if (self) { self.delaysContentTouches = NO;}return self;}- (instancetype)initWithFrame:(CGRect)frame {self = [super initWithFrame:frame];if (self) { self.delaysContentTouches = NO;}return self;}- (BOOL)touchesShouldCancelInContentView:(UIView *)view {if ([view isKindOfClass:[UIButton class]]) { return YES;}return [super touchesShouldCancelInContentView:view];}
這就是UIScrollView的讓UIButton高亮方法,然而UITableview相比更加複雜些
UITableView:
在iOS7和iOS8中的視圖結構是不同的,且存在著很多我們在編碼時永遠接觸不到的視圖,但我們可通過Debug將其subviews逐個逐個找出來。這關係到我們這個問題坑比較深的層次。
iOS7:UITableView中存在n+1個UIScrollView,一個是UITableView本身,另外n個村在於UITableViewCell月cell的contenView之間,類名為UITableVieCellScrollVIew,在iOS8已經移除。
iOS8:UITableView中存在2個UIScrollView,一個是UITableView本身,另外一個存在於UITableView與UITableViewCell之間,類名為UITableViewWrapperView。需要注意的是,UITableViewWrapperView在iOS7中並不是一個UIScrollView。
理解後直接貼代碼
@implementation ResponseTableView- (instancetype) initWithCoder : (NSCoder *) aDecoder{self = [super initWithCoder:aDecoder];if (self) { self.delaysContentTouches = NO; //因為 UITableViewWrapperView 在iOS7不屬於UIScrollView //iOS7 for (id obj in self.subviews) { if ([NSStringFromClass([obj class]) isEqualToString:@"UITableViewCellScrollView"]) { UIScrollView *scrollView = (UIScrollView *) obj; scrollView.delaysContentTouches = NO; break; } } //ios 8 for (id view in self.subviews) { if ([NSStringFromClass([view class]) isEqualToString:@"UITableViewWrapperView"]) { if ([view isKindOfClass:[UIScrollView class]]) { UIScrollView *scrollView = (UIScrollView *) view; scrollView.delaysContentTouches = NO; } break; } }}return self;}- (BOOL) touchesShouldCancelInContentView : (UIView *) view {if ([view isKindOfClass:[UIButton class]]) { return YES;}return [super touchesShouldCancelInContentView:view];}
以上,就能解決Button延遲高亮的方法.