你好,歡迎來到IOS教程網

 Ios教程網 >> IOS使用技巧 >> IOS技巧綜合 >> UITableView或UIScrollVIew上的UIButton的高亮效果

UITableView或UIScrollVIew上的UIButton的高亮效果

編輯:IOS技巧綜合
[摘要]本文是對UITableView或UIScrollVIew上的UIButton的高亮效果的講解,對學習IOS蘋果軟件開發有所幫助,與大家分享。

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延遲高亮的方法.

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved