如何检测UITableView的拖动结束事件?

UITableView的拖动结束时,我需要得到通知。

但我正在处理UITableView的类别,所以我不能使用scrollViewDidEndDragging:willDecelerate:将其归档。

我试图用KVO来观察dragging关键path:

 [self addObserver:self forKeyPath:@"dragging" options:NSKeyValueObservingOptionNew context:nil]; 

但是observeValueForKeyPath:ofObject:change:context:没有被调用,因为UITableView.dragging没有和setter,这个属性不符合KVO。

有没有其他的方法来存档这个期望使用scrollViewDidEndDragging:willDecelerate:

任何帮助,感激! 谢谢!

编辑:我的解决scheme下面是第一个想到的事实,结果是相当hacky,可能是不安全的情况下,苹果决定改变UIScrollView类的内部。 请参阅Mazyodbuild议的答案 ,应该更安全,更直接。


这是依赖于实现的,在未来的iOS更新中可能会被Apple更改,但是目前UIScrollView类似乎依赖于手势识别器来pipe理用户交互,而UITableView作为scroll view类的子类也是一样的。

如果你去UIKit框架的UIScrollView.h,你可以注意到一个可疑的_pan伊娃,它有一个idtypes,但似乎实际上是一个UIPanGestureRecognizer

所以我尝试了这个,似乎工作。

  [_tableView addObserver: self forKeyPath: @"pan.state" options: NSKeyValueObservingOptionNew context: nil]; 

拖动表视图时,手势识别器的state发生多次变化,当您停止拖动时, state会将其最后更改的值更改为UIGestureRecognizerStateEnded的值。

请注意,虽然这似乎有伎俩,但其他一些问题可能会阻碍你。 在一个类别中覆盖现有的类方法通常不是一个好主意,因为原来的实现在那之后变得不可访问。 NSKeyValueObserving非正式协议的文档声明

NSObject提供了NSKeyValueObserving协议的实现,为所有对象提供自动观察能力。

因此,如果您重写了observeValueForKeyPath:ofObject:change:context:在一个类别中,默认的实现将是不可访问的(我们不能确定UITableViewUIScrollView不用用户KVO的东西)。 这可能会导致一些意外的错误。

Egor Chiglintsev的回答提醒我,我可以观察到已经在UIScrollView暴露的panGestureRecognizer属性。 它应该比pan更安全。 但是,后来..我发现我可以把自己作为一个目标!

 [_scrollView.panGestureRecognizer addTarget:self action:@selector(gestureRecognizerUpdate:)]; 

这对我很好!