How to popup a UIPickerView from the bottom of a UIScrollView in response to UITextField selection
It says to do this with
For the life of me, that wouldn’t work. I could get it to popup sometimes, but with a horrible messed up UIPicker. I added the UIPickerView to another UIView, which was put into a UIViewController, and handed that to the above method.
This worked brilliantly, BUT after animating from the bottom the background would go completely white. Not good.
Welcome UIActionSheet
It is not available via the Interface Builder, which is where I endeavor to do all my UI (against the recommendations of everyone in the office.)
Basically, you create a UIActionSheet, add your UIPickerView to it, set the callback delegate (to get which button is clicked) and your away!
Code…
return (NSString*)[currentData objectAtIndex:row+1];
}
– (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
– (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return [currentData count] – 1;
}
Put that into your controller (and smoke it.)
UIActionSheet *menu = [[UIActionSheet alloc] initWithTitle:[currentData objectAtIndex:0]
delegate:self
cancelButtonTitle:@"Done"
destructiveButtonTitle:@"Cancel"
otherButtonTitles:nil];
// Add the picker
UIPickerView *pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0,185,0,0)];
pickerView.delegate = self;
pickerView.showsSelectionIndicator = YES; // note this is default to NO
[menu addSubview:pickerView];
[menu showInView:self.view];
[menu setBounds:CGRectMake(0,0,320, 700)];
[pickerView release];
[menu release];
}
It’s not pretty, but it works. Again put that into your controller.
Respond to UIActionSheet buttons..
if(buttonIndex==1){
if(currentField == location){
if(!completedOnce){
[website becomeFirstResponder];
}
}else{
completedOnce = YES;
}
}
}
Again, in your controller. (I left in my actual code, to give an idea..)
What mine basically does is as follows
- Setup a couple of arrays with data (content for UIPickerView) (for reference different UITextFields)
- When a UITextField gets textFieldShouldBeginEditing I return NO and instead call showPicker.
- Before showPicker is called, I set an instance variable to the array the UITextField relates to. This sets it up for the UIPickerView to use.
- showPicker shows the ActionSheet, with the data it needs.
- showPicker returns, calling the clickedButtonAtIndex
- Then I decide what to do with it
There are some minor details I have left out, but you should be able to fill in the gaps.
[Edit]
If you are wondering why I return the currentData objectAtIndex:row+1 it is because my arrays have the first Item the title of the UIPickerView.
@"Select Your Region",
@"Waikato",
@"Hawkes Bay",
@"Marlborough",
@"Taranaki",
@"Gisborne",
@"Bay of Plenty",
@"Nelson",
@"Otago",
@"Southland",
@"Northland",
@"Manawatu-Wanganui",
@"West Coast",
@"Canterbury",
@"Wellington",
@"Auckland",
@"Tasman", nil] retain];
Don’t forget to add
to your .h file.
[EDIT]
To get the selectedIndex from the UIPicker, you need to add the following to your controller. This is in response to a comment below. I haven’t been deving the iPhone recently so I only guessed the below solution is correct (cherry picked it out of my code). If not please point it out and I’ll go back and work it out again.
selectedScrollIndex = row;
}
Related Posts
In: Iphone · Tagged with: iPhone, UIActionSheet, UIScrollView, UIView
on March 29, 2009 at 11:19 pm
Permalink
Great solution! But how did you manage to retrieve the selected value from the embedded picker?
on March 30, 2009 at 6:14 am
Permalink
Hi mate,
you helped me a lot. I have aproblem though. My pickerview is not populated. I have my arrays (2 columns) but it seems the data does not get in the picker. This is the code I have to populate it
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
NSString *title = nil;
switch(component)
{
case 0:
if(row < [columnOneArray count])
{
title = [columnOneArray objectAtIndex:row];
}
break;
case 1:
if(row < [columnTwoArray count])
{
title = [columnTwoArray objectAtIndex:row];
}
break;
}
return title;
}
on March 30, 2009 at 7:14 am
Permalink
…one of my pickerView methods was mispelled.
on March 30, 2009 at 10:32 am
Permalink
I believe you use
– (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
selectedScrollIndex = row;
}
on March 30, 2009 at 10:38 am
Permalink
@Alex, mis-spelt method names are my biggest weakness. Also variables. Hurts me.
Make use of declaring interfaces for your classes and it will give warnings that you are missing methods, provided it is a required method and not an optional one.
on April 10, 2009 at 10:46 am
Permalink
OK. I’m a noob. How do I call showPicker? I’m wanting it to happen when I go to edit a text field.
on April 14, 2009 at 12:45 pm
Permalink
When a UITextField gets textFieldShouldBeginEditing I return NO and instead call showPicker.
Thats the kicker, you need to write in ‘textFieldShouldBeginEditing’ and then call showPicker, then return No.
So the controller gets the textfield callback (via the being the delegate for the UITextField). It asks the controller should I show a keyboard, you say NO, and instead call the showpicker method.
on January 19, 2010 at 2:28 pm
Permalink
I know this is old, but as a side note this can introduce a bug if the ActionSheet is dismissed while the picker is still animating the selection. The user will think that they have finished the selection but didSelectRow will not have been called before the ActionSheet dismissal. This can create problems if the UIPickerViewDelegate didSelectRow and the UIActionSheetDelegate willDismissWithButtonIndex both operate on the same property. I got hit with this and it took me a while to figure out what was going on.
on May 24, 2010 at 7:55 pm
Permalink
If anyone wants a fully functional reusable PickerControl that pops up and goes away with a combo box widget for your UITextFields that you can configure easily in IB email me at servertoodATgmail.com.
You dont have to write any code just implement a protocol to get the data by a key.
on August 17, 2010 at 8:24 am
Permalink
to use this solution in iPad as well, just correct the Rect of the Picker:
// Add the picker
UIPickerView *pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0,185,0,0)];
to
// Add the picker
UIPickerView *pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0,185,320,216)];
best regards & thanks
on February 11, 2011 at 1:23 am
Permalink
do u have a complete sample code
on May 16, 2011 at 1:43 am
Permalink
Thanks for the info. A code sample would go a long way here.