在做demo时, 发现 UITableViewCell
中的 UIButton
短按一次看不到默认的变灰效果, 停留稍长才能变灰, 比如twitter官方客户端用户头像, 微博的转评赞三按钮。 微博各类客户端的头像和其他按钮也是这样, 头像很多直接是imageView加手势。 这方面细节处理的最好的是 Instagram 不管短按长按都会灰, 这样才有打击感。
经一番搜索之后得知 UITableView
做为 UIScrollView
的子类,拥有 delaysContentTouches
的布尔属性, 且默认为 YES
, 即延迟响应 UIScrollView
子视图中的事件, 在这个短暂的延迟中, 如果触摸发生了移动, 则响应为滚动事件, 若没有移动且子视图中有 UIControl
类型且触摸位置处于该控件的话则被立即传递并触发相应事件。 所以当短按 UIButton
时, 先被系统判断为不是滚动事件才被传给子视图控件, 但高亮效果的动画被绕过了, 事件被直接传递。 所以只有当手指停留稍长时间时, 才度过了延迟时间从而看到了高亮效果。
若想要让 UIButton
短按长按均可显示高亮特效的话, 就是去掉这个延迟。 在你创建完表视图对象的地方, 或其初始化方法中加入以下代码, 将其默认的值改为 NO
。
1
|
someTableViewObject.delaysContentTouches = NO;
|
但这个时候又会发现, 当手指以 UIButton
区域做为滚动操作的起始点的话, UIScrollView
就不响应滚动的手势动作了。
如果希望 UITableView
上的所有地方总能响应滚动事件的话, 就需要子类化 UITableView
并重写其从父类 UIScrollView
继承来的如下方法了
1
2
3
4
5
6
|
// 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
的结构变化
1
2
3
4
5
6
7
|
// iOS 6
<UITableViewCell>
| <UITableViewCellContentView>
// iOS 7
<UITableViewCell>
| <UITableViewCellScrollView>
| | <UITableViewCellContentView>
|
iOS 7 的 UITableViewCellContentView
又多了一级父视图 UITableViewCellScrollView
, 看名字带有 ScrollView
, 但是其好像并不会再多一级事件响应的延迟了。
之前写错了,UITableViewCellScrollView
也要去掉延迟。
1
2
3
4
5
6
7
8
9
|
// 我是在 cell 的初始化方法中做的处理
for
(UIView *currentView in self.subviews){
if
([NSStringFromClass([currentView
class
]) isEqualToString:@
"UITableViewCellScrollView"
])
{
UIScrollView *sv = (UIScrollView *) currentView;
[sv setDelaysContentTouches:NO];
break
;
}
}
|