【IOS】關於處於表視圖行單元 contentView 中的 UIButton 短按不產生高亮效果的

在作demo時, 發現 UITableViewCell 中的 UIButton 短按一次看不到默認的變灰效果, 停留稍長才能變灰, 好比twitter官方客戶端用戶頭像, 微博的轉評贊三按鈕。 微博各種客戶端的頭像和其餘按鈕也是這樣, 頭像不少直接是imageView加手勢。 這方面細節處理的最好的是 Instagram 無論短按長按都會灰, 這樣纔有打擊感。動畫

經一番搜索以後得知 UITableView 作爲 UIScrollView 的子類,擁有 delaysContentTouches 的布爾屬性, 且默認爲 YES, 即延遲響應 UIScrollView 子視圖中的事件, 在這個短暫的延遲中, 若是觸摸發生了移動, 則響應爲滾動事件, 若沒有移動且子視圖中有 UIControl 類型且觸摸位置處於該控件的話則被當即傳遞並觸發相應事件。 因此當短按 UIButton 時, 先被系統判斷爲不是滾動事件才被傳給子視圖控件, 但高亮效果的動畫被繞過了, 事件被直接傳遞。 因此只有當手指停留稍長時間時, 才度過了延遲時間從而看到了高亮效果。spa

若想要讓 UIButton 短按長按都可顯示高亮特效的話, 就是去掉這個延遲。 在你建立完表視圖對象的地方, 或其初始化方法中加入如下代碼, 將其默認的值改成 NO 。code

someTableViewObject.delaysContentTouches = NO;

但這個時候又會發現, 當手指以 UIButton 區域作爲滾動操做的起始點的話, UIScrollView就不響應滾動的手勢動做了。orm

若是但願 UITableView 上的全部地方總能響應滾動事件的話, 就須要子類化 UITableView 並重寫其從父類 UIScrollView 繼承來的以下方法了對象

// default returns YES if view isn't a UIControl
// Returns whether to cancel touches related to the content subview and start dragging.
- (BOOL)touchesShouldCancelInContentView:(UIView *)view{ 
       // 即便觸摸到的是一個 UIControl (如子類:UIButton), 咱們也但願拖動時能取消掉動做以便響應滾動動做
       return YES;
}

經過 UIScrollView 頭文件中的註釋, 以及蘋果官方文檔的說明能夠得知, 由於其默認若是事件在 UIControl 或其子類響應時, 返回爲 NO, 即 即便觸摸發生移動, 也不響應爲滾動事件。 因此讓其始終返回 YES, 即 UIScrollView 在屏幕上顯示的任何位置的觸摸事件, 若是發生移動, 都可響應爲滾動事件。繼承

iOS 7 UITableViewCell 的結構變化

// iOS 6
    <UITableViewCell>
       | <UITableViewCellContentView>
// iOS 7
    <UITableViewCell>   
       | <UITableViewCellScrollView>
       |    | <UITableViewCellContentView>

iOS 7 的 UITableViewCellContentView 又多了一級父視圖 UITableViewCellScrollView, 看名字帶有 ScrollView , 可是其好像並不會再多一級事件響應的延遲了事件

以前寫錯了,UITableViewCellScrollView 也要去掉延遲。文檔

// 我是在 cell 的初始化方法中作的處理
for (UIView *currentView in self.subviews){
    if ([NSStringFromClass([currentView class]) isEqualToString:@"UITableViewCellScrollView"])
    {
        UIScrollView *sv = (UIScrollView *) currentView;
        [sv setDelaysContentTouches:NO];
        break;
     }
}
相關文章
相關標籤/搜索