在做demo时, 发现 UITableViewCell
中的 UIButton
短按一次看不到默认的变灰效果, 停留稍长才能变灰, 比如twitter官方客户端用户头像, 微博的转评赞三按钮。 微博各类客户端的头像和其他按钮也是这样, 头像很多直接是imageView加手势。 这方面细节处理的最好的是 Instagram 不管短按长按都会灰, 这样才有打击感。
经一番搜索之后得知 UITableView
做为 UIScrollView
的子类,拥有 delaysContentTouches
的布尔属性, 且默认为 YES
, 即延迟响应 UIScrollView
子视图中的事件, 在这个短暂的延迟中, 如果触摸发生了移动, 则响应为滚动事件, 若没有移动且子视图中有 UIControl
类型且触摸位置处于该控件的话则被立即传递并触发相应事件。 所以当短按 UIButton
时, 先被系统判断为不是滚动事件才被传给子视图控件, 但高亮效果的动画被绕过了, 事件被直接传递。 所以只有当手指停留稍长时间时, 才度过了延迟时间从而看到了高亮效果。
若想要让 UIButton
短按长按均可显示高亮特效的话, 就是去掉这个延迟。 在你创建完表视图对象的地方, 或其初始化方法中加入以下代码, 将其默认的值改为 NO
。
someTableViewObject.delaysContentTouches = NO;
但这个时候又会发现, 当手指以 UIButton
区域做为滚动操作的起始点的话, UIScrollView
就不响应滚动的手势动作了。
如果希望 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; } }