Allowing user to select a UIPickerView row by tapping


I'm trying to use a UIPicker View with a behavior somehow different of what's usually seen in iPhone code examples.

What I want to do is to allow users to scroll through the picker contents, but not to select a picker's row automatically (using the "didSelectRow" method from picker's delegate). Instead, I want to allow the user to touch the center row of the picker, which gets highlighted, and becomes the selection.

Is there any way to achieve this?

Thanks in advance.


Add a gesture recogniser to the UIPickerView which triggers a target method in your object:

myGR = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(pickerTapped:)]; [myPicker addGestureRecognizer:myGR]; // target method -(void)pickerTapped:(id)sender { // your code }



make a new UIControl

<ul><li>same position as the UIPickerView</li> <li>[yourcontrol setBackGroundColor: [UIColor clearColor]];</li> </ul></li> <li>

make a method

</li> </ol> - (IBAction) pickerControlTapped { [yourpicker selectRow: rand()% yourpickersize inComponent: 0 animated: YES]; }

.3. make a connection between 1 and 2

[yourcontrol addTarget: self action: @selector(pickerControlTapped) forControlEvents: UIControlEventTouchUpInsied];


Building on Martin Linklater's answer to support tapping on the pickers other rows: Has some magic numbers but works for me.

- (void) pickerTapped:(UITapGestureRecognizer*)gestureRecognizer { CGPoint location = [gestureRecognizer locationInView:self.pickerView]; CGFloat halfViewHeight = self.pickerView.frame.size.height / 2; NSInteger row = -1; if (location.y < halfViewHeight - 22 && location.y > halfViewHeight - 66) { row = [self.pickerView selectedRowInComponent:0] - 1; } else if (location.y < halfViewHeight + 22 && location.y > halfViewHeight - 22) { row = [self.pickerView selectedRowInComponent:0]; } else if (location.y < halfViewHeight + 66 && location.y > halfViewHeight + 22) { row = [self.pickerView selectedRowInComponent:0] + 1; } if (row >= 0 && row < [self.content count]) { id element = [self.content objectAtIndex:row]; if (element) { [self.pickerView selectRow:row inComponent:0 animated:YES]; // do more stuff } } }


I have a relatively simple solution to this problem that has worked well for me. Using a hidden custom button you can achieve the tap functionality without a gesture recogniser. This solution works for a picker with one component, however I'm sure it could be adapted to work with more.

Firstly add a button, either in the Interface Builder or programatically. Make it hidden and as wide as the picker then place it so that it sits exactly in the centre of the picker and also in front of it in the view hierarchy.

I'm using an IBAction like this to show my picker. However it's really up to you how you show and hide the picker.

- (IBAction)showPicker:(id)sender { _picker.hidden = NO; _buttonPicker.hidden = NO; }

All the action for choosing the picker value happens in an IBAction for the UIControlEventTouchUpInside event, something like this.

- (IBAction)selectPicker:(id)sender { //Hide the button so that it doesn't get in the way _buttonPicker.hidden = YES; //Make sure we're within range NSInteger max = _values.count; NSInteger row = [_picker selectedRowInComponent:0]; if(row >= 0 && row < max) { NSString *value = [_values objectAtIndex:row]; //Set the label value and hide the picker _label.text = value; _picker.hidden = YES; } }

I've slightly modified the code for this answer from working code so apologies if it's broken at all.


There are only 2 delegates for UIPickerView.

<ul><li><a href="http://developer.apple.com/iPhone/library/documentation/UIKit/Reference/UIPickerViewDelegate_Protocol/Reference/UIPickerViewDelegate.html" rel="nofollow">UIPickerViewDelegate</a></li> <li><a href="http://developer.apple.com/iphone/library/documentation/iPhone/Reference/UIPickerViewDataSource_Protocol/Reference/Reference.html" rel="nofollow">UIPickerViewDataSource</a></li> </ul>

So, we can use only 7 methods to control UIPickerView by delegate.

<em>– pickerView:rowHeightForComponent:<br /> – pickerView:widthForComponent:<br /> – pickerView:titleForRow:forComponent:<br /> – pickerView:viewForRow:forComponent:reusingView:<br /> – pickerView:didSelectRow:inComponent:<br /> – numberOfComponentsInPickerView:<br /> – pickerView:numberOfRowsInComponent:</em>


In <a href="http://developer.apple.com/iPhone/library/documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html" rel="nofollow">UITableViewDelegate case</a>, there are more methods for UITableView for managing selections. such as, <em>– tableView:willSelectRowAtIndexPath:<br /> – tableView:didSelectRowAtIndexPath:<br /> – tableView:willDeselectRowAtIndexPath:<br /> – tableView:didDeselectRowAtIndexPath:</em>


In UIPickerViewDelegate case, there is only 1 method for responding to row selection.

<em>– pickerView:didSelectRow:inComponent:</em>


  • Table view return wrong values when scrolling
  • How to pull the text value for a UITextField inside a UITableViewCell?
  • UIButton CustomButton Image Not Appearing
  • Creating Buttons by looping through an array
  • How to make UIPickerView resignFirstResponder if user clicks in other place then UIPickerView
  • How to Push one UIview to another UIview in ios using Animation concept?
  • Using cell (returned from cellForRow method) in didSelectRow method
  • How to use PhoneNumberFormatter class to format phone number in UITextField?
  • Protocol extension and addTarget is crashing with NSInvalidArgumentException
  • View tableview cell text on table view cell button
  • Allowing user to select a UIPickerView row by tapping
  • Adding a button inside a popover
  • UITextField keyboard can't type anything
  • NSUserDefaults not working with UITableView in Swift
  • how to check the condition for UIButtons in UITableview
  • How to add next and previous buttons programmatically in iPhone?
  • Label blocking a button click
  • LandScape/Portrait size differ iOS
  • clicking button within UITableview cell gives wrong result while search
  • How can I save a second row of UIPickerView to NSUserDefaults?
  • pushViewController from another class
  • How to track where the right callout accessory view is when it was tapped on
  • Using UIButton to navigate between views
  • AudioUnit framework not found
  • [UILabel numberOfComponentsInPickerView:]: unrecognized selector sent to instance …]
  • Objective-C: Tabbaritem tapped->Method Called-> But WebView not refreshed
  • Embed javascript in PHP echo
  • UItableView Replacing Checkmarks with UIButton
  • Type definition: expected UnionAll, got TypeVar
  • How to remove duplicate buttons
  • How do I stop js files being cached in IE?
  • How to generate random events in android?
  • Yii: any way to save the images in compressed form?
  • Multiple storyboards: should I use a singleton pattern to cache them?
  • Auto Height of UICollectionView inside UITableViewCell
  • “[CALayer release]: message sent to deallocated instance” when dismissing modal view controller
  • “A GKScore must specify a leaderboard.”
  • Jquery UI Sortable, move item automatically
  • Inversing an interpolation of rotation
  • custom UITableViewCell with image for highlighting