I need to get notified when an UITableView
's drag has come to an end.
But I'm working on an UITableView's category, so I can't use scrollViewDidEndDragging:willDecelerate:
to archive this.
I tried use KVO to observe on dragging
Key Path:
[self addObserver:self forKeyPath:@"dragging" options:NSKeyValueObservingOptionNew context:nil];
But observeValueForKeyPath:ofObject:change:context:
didn't get called, since UITableView.dragging doesn't have and setter and this property is not compliant with KVO.
Is there any other method to archive this expect for using scrollViewDidEndDragging:willDecelerate:
?
Any help is grateful! Thanks!
Edit: My solution below was the first thing to come in mind and turned out to be rather hacky and may be unsafe to use in case Apple decides to change the internals of the UIScrollView
class. See the answer suggested by Mazyod which should be safer and more straightforward.
This is implementation-dependent and may be changed by Apple in future iOS updates, but currently UIScrollView
class seems to rely on gesture recognizers for managing user interaction and UITableView
being a subclass of the scroll view class does the same.
If you go to UIScrollView.h of the UIKit framework, you can notice a suspicious _pan
ivar which has an id
type, but seems to actually be a UIPanGestureRecognizer
.
So I've tried this, and it seems to work.
[_tableView addObserver: self
forKeyPath: @"pan.state"
options: NSKeyValueObservingOptionNew
context: nil];
When dragging the table view, state
of the gesture recognizer changes several times, and when you stop dragging, state
receives its last change to the value of UIGestureRecognizerStateEnded
.
Please note that although this seems to do the trick, some other problem may stand in your way. It is generally not a good idea to override existing class methods in a category since the original implementation becomes inaccessible after that. Documentation on the NSKeyValueObserving
informal protocol states that
NSObject provides an implementation of the NSKeyValueObserving protocol that provides an automatic observing capability for all objects.
So if you override observeValueForKeyPath:ofObject:change:context:
in a category, the default implementation will be inaccessible (and we cannot be sure that UITableView
or UIScrollView
do not user KVO for something). That may cause some unexpected errors.
Egor Chiglintsev's answer reminded me I can observe the panGestureRecognizer
property already exposed in UIScrollView
. It should be much safer than pan
. But then.. I found out I can just add myself as a target!
[_scrollView.panGestureRecognizer addTarget:self action:@selector(gestureRecognizerUpdate:)];
This works great for me!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With