简要:对于 UITableView、UICollectionView,如果要判断用户是否正在拖拽,要使用
isTracking
属性代替isDragging
属性
在 iOS 里,键盘弹起之后,如果用户想让键盘收起,一个常见的做法是当用户上下划动一下 tableView 的时候就把键盘收起。比如京东商品评论就是这么做的。
那么如何实现这个效果呢?最简单的想法是:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
[self.view endEditing:YES];
}
但这样写有一个问题:除了用户手动地上下划动,其他原因造成的滚动也会触发这个回调函数。例如,当键盘弹出的时候,为了让 tableView 的内容能完全显示,往往会将 tableView 的底部 inset 改为键盘高度,此时也会触发scrollViewDidScroll:
事件。如果像上面写的话,就会导致键盘又被收起来了。
所以,我们自然想到用 scrollView 的isDragging
属性来判断一下滚动的原因,是否是用户拖拽导致的:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.isDragging) {
[self.view endEditing:YES];
}
}
理论上这样写应该没有任何问题,然而实际却不能用!因为测试发现,即使不是用户划动,isDragging
属性也可能为YES
。比如上面的例子,由于改变 inset 导致的滚动,用户并没有拖拽,然而isDragging
属性仍为YES
。
也就是说,isDragging
属性在 UITableView 上是不能用的,它的值并不总是正确,并不能正确反映出用户是否在拖拽。UICollectionView 也有同样的问题。
要解决这个问题,我们只能用isTracking
代替isDragging
。所以改成:
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView.isTracking) {
[self.view endEditing:YES];
}
}
就没有问题了。
查了一下苹果文档,并没有相关的解释,看来又是官方实现的一个小 bug 了。
p.s. 文中的效果也可以用下面这个方法实现:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
[self.view endEditing:YES];
}