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.