Reputation: 2773
How would I go about adding gesture events to uipickerview to change tabs? I have to create a custom class, however, I don't know how to handle the uipickerview. I current have gestures present in uiviews to do this, but I'm having trouble with the uipickerview.
My code for the views:
#define HORIZ_SWIPE_DRAG_MIN 100
CGPoint mystartTouchPosition;
BOOL isProcessingListMove;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint newTouchPosition = [touch locationInView:self.view];
if(mystartTouchPosition.x != newTouchPosition.x || mystartTouchPosition.y != newTouchPosition.y) {
isProcessingListMove = NO;
}
mystartTouchPosition = [touch locationInView:self.view];
[super touchesBegan:touches withEvent:event];
}
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = touches.anyObject;
CGPoint currentTouchPosition = [touch locationInView:self.view];
// If the swipe tracks correctly.
double diffx = mystartTouchPosition.x - currentTouchPosition.x + 0.1; // adding 0.1 to avoid division by zero
double diffy = mystartTouchPosition.y - currentTouchPosition.y + 0.1; // adding 0.1 to avoid division by zero
if(abs(diffx / diffy) > 2.5 && abs(diffx) > HORIZ_SWIPE_DRAG_MIN)
{
// It appears to be a swipe.
if(isProcessingListMove) {
// ignore move, we're currently processing the swipe
return;
}
if (mystartTouchPosition.x < currentTouchPosition.x) {
isProcessingListMove = YES;
self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:0];
return;
}
else {
isProcessingListMove = YES;
self.tabBarController.selectedViewController = [self.tabBarController.viewControllers objectAtIndex:2];
return;
}
}
else if(abs(diffy / diffx) > 1)
{
isProcessingListMove = YES;
[super touchesMoved:touches withEvent:event];
}
}
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
isProcessingListMove = NO;
[super touchesEnded:touches withEvent:event];
}
Thanks for the help.
Upvotes: 2
Views: 2109
Reputation: 675
You CAN subclass UIPickerView. The problem is that it's comprised of nine subviews, one of which, called UIPickerTable, is receiving the touch events like touchesBegan:withEvent:
to the rows you want. I was able to successfully intercept these with the code included at the end of this post:
Responding to touchesBegan in UIPickerView instead of UIView
The other answers/comments there are helpful too. I wanted to clear the air, not for someone doing something non-standard (as in this question), but for someone who arrived here wishing to subclass UIPickerView, because the first line of the accepted answer is dead wrong.
Upvotes: 2
Reputation: 102296
ZT> You can't subclass UIPickerView. "In order to make the picker view spin longer, I subclassed UIPickerView. My subclass had exactly one method" from Longer Spinning and Blurring. Also see UIPickerView Class Reference: "The UIDatePicker class uses a custom subclass of UIPickerView to display dates and times."
Upvotes: -1
Reputation: 64428
You can't subclass UIPickerView.
However, since a picker view must be displayed in another view (since it doesn't take up the entire screen) you can trap the touches in that view's controller and filter for gestures.
(Assuming I understand what your trying to do...) I would warn that swiping a picker view to change tabs is a non-standard UI and will probably confuse your users. Since a picker view is perceived as a type of control, they will expect only the normal spinning action of the picker. How would they even know to swipe a picker view horizontally?
Upvotes: 0