views:

312

answers:

1

Is it possible to control when the UITableView scrolls in my own code.

I am trying to get behaviour where a vertical swipe scrolls and a horizontal swipe gets passed through to my code (of which there are many example)

BUT

I want a DIAGONAL swipe to do nothing, i.e the UITableView should not even begin scrolling.

I tried catching it in here

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView

but the scrollView.contentOffset.x is always 0 so I cannot detect a horizontal movement.

I also tried subclassing UITableView and implementing

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event

etc..

but the UITableView (and I guess it's parent UIScrollView) start to scroll before the touches are notified?

To re-iterate, I want the UITableView scrolling to be locked if a diagonal swipe is made, but to scroll vertically normally.

(This behaviour can be seen in Tweetie(Twitter) for the iPhone)

Thanks for any help!

A: 

If you can work with 3.2 or later, the UIGestureRecognizer suite should allow this. There are a series of calls allowing some gestures to cancel or interoperate with other gestures, and you should be able to create a custom diagonal swipe gesture that cancels other gestures but does not actually do anything itself.

Prior to 3.2 the UIScrollView gesture handling is essentially undocumented. You can detect taps but not movements through the standard touchesBegan UIResponder calls. I think that once it detects movement it commandeers the run loop and captures all events, bypassing the normal event chain.

Note that setContentOffset is always called. You can create a subclass of UIScrollView and when you detect a diagonal shift during event tracking do not pass it to super. I do not know if, or how well this would work but it is somewhere to start.

drawnonward
Thanks, UIGestureRecognizer handles swipe detection far better than I had achieved with any other method. I am targetting the iPad so works great :-)
Jonesy
Incidentally, you need to do recognizer.cancelsTouchesInView = YES; in your handler to achieve the effect I was after.
Jonesy