Gone Coding Logo

Gone Coding

Detail is everything

Adding “Tap to Select” to a UIPickerView in iOS

The standard UIPickerView in iOS will only fire selection messages when the user has changed the selection to a different row than the current one.

Sometimes that’s not the desired behaviour.

The following code snippet will intercept tap gestures on a UIPickerView and determine if the tap was within the selection indicator of the UIPickerView:

First, we’ll add a UITapGestureRecognizer to intercept tap gestures. Note, that we don’t want to cancel the touches because the UIPickerView should still do it’s thing spinning the wheel and all.

- (void)viewDidLoad
{
   [super viewDidLoad];

   UITapGestureRecognizer* gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pickerViewTapGestureRecognized:)];
   gestureRecognizer.cancelsTouchesInView = NO;

   [self.pickerView addGestureRecognizer:gestureRecognizer];
}

Second, we’ll check, if the tap was within the selection indicator of the UIPickerView (assuming that the selection indicator uses about 15% of the height of the UIPickerView — you may have to adjust this value):

- (void)pickerViewTapGestureRecognized:(UITapGestureRecognizer*)gestureRecognizer
{
   CGPoint touchPoint = [gestureRecognizer locationInView:gestureRecognizer.view.superview];

   CGRect frame = self.pickerView.frame;
   CGRect selectorFrame = CGRectInset( frame, 0.0, self.pickerView.bounds.size.height * 0.85 / 2.0 );

   if( CGRectContainsPoint( selectorFrame, touchPoint) )
   {
      NSLog( @"Selected Row: %i", [self.currentArticles objectAtIndex:[self.pickerView selectedRowInComponent:0]] );
   }
}

You should NOT implement the

- (void)pickerView:(UIPickerView*)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component

since we’re detecting selection on our own now.

Posted by Michael Sedlaczek · Cocoa Touch · Development · Objective C · UIPickerView · iOS · Featured