20

Here is a screenshot of what I did till now:

enter image description here

So what I am trying to do is when you select "pick a name" Textfield I need a Picker to show up, with the input @"Jack".

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
sillersam
  • 217
  • 1
  • 2
  • 5
  • set and connect textfield with delegate in interface builder and same for UIPickrView.. – PJR Aug 17 '11 at 10:08

8 Answers8

68

Since iOS 3.2, UITextField supports the inputView property to assign a custom view to be used as a keyboard, which provides a way to display a UIPickerView:

You could use the inputView property of the UITextField, probably combined with the inputAccessoryView property. You assign your pickerView to the inputView property, and, to dismiss the picker, a done button to the inputAccessoryView property.

UIPickerView *myPickerView = [[UIPickerView alloc] init];
//myPickerView configuration here...
myTextField.inputView = myPickerView;

Like that. This will not give you a direct way to dismiss the view since your UIPickerView has no return button, which is why I recommend to use the inputAccessoryView property to display a toolbar with a done button (the bar is just for aesthetics, you might as well just use a UIButton object):

UIToolbar *myToolbar = [[UIToolbar alloc] initWithFrame:
 CGRectMake(0,0, 320, 44)]; //should code with variables to support view resizing
UIBarButtonItem *doneButton =
 [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
 target:self action:@selector(inputAccessoryViewDidFinish)];
 //using default text field delegate method here, here you could call
 //myTextField.resignFirstResponder to dismiss the views
[myToolbar setItems:[NSArray arrayWithObject: doneButton] animated:NO];
myTextField.inputAccessoryView = myToolbar;
Tom
  • 2,674
  • 1
  • 25
  • 33
  • Im doing what you say here and assigning the toolbar to my inputAccessoryView but the toolbar has the background missing and the flexible space doesnt seem to work. The only difference here is that I created the toolbar in XIB. Do you know what could be going wrong? – RPM Jun 29 '13 at 00:35
  • Ok - I got it to work, though I dont have an explanation for it. I was creating the toolbar as a subview to the parent view (scrollview) but what I did was create the view outside of the subview (outlets still connected) and then in code assigned the inputAccessoryView as you showed above and that worked ! – RPM Jun 29 '13 at 00:38
  • 2
    Thanks. -(void) inputAccessoryViewDidFinish { [self.myTextField resignFirstResponder]; } – Baryon Lee Jan 09 '14 at 08:03
14

I use this and find this a lot cleaner than adding a subview and animating the UIPicker

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
responder = textField;

    if ([textField isEqual:self.txtBirthday]) {
    UIDatePicker *datepicker = [[UIDatePicker alloc] initWithFrame:CGRectZero];
    [datepicker setDatePickerMode:UIDatePickerModeDate];

    textField.inputView = datepicker;
    }

    return YES;
}
Abizern
  • 146,289
  • 39
  • 203
  • 257
geekay
  • 1,655
  • 22
  • 31
4

it will work for you .. i have edited it .and for that you have to set delegate for textfield. and create a UIPIckrView in NIb file.

- (BOOL) textFieldShouldBeginEditing:(UITextView *)textView
{
    pickrView.frame = CGRectMake(0, 500, pickrView.frame.size.width,    pickrView.frame.size.height);
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:.50];
    [UIView setAnimationDelegate:self];
    pickrView.frame = CGRectMake(0, 200, pickrView.frame.size.width, pickrView.frame.size.height);
    [self.view addSubview:pickrView];
    [UIView commitAnimations];
    return NO;
}
Andy Obusek
  • 12,614
  • 4
  • 41
  • 62
PJR
  • 13,052
  • 13
  • 64
  • 104
  • please read my first comment first. im getting 1 error : "pickrView undeclared" – sillersam Aug 17 '11 at 10:08
  • IBOutlet UIPickerView *pickrView; write this in your interface and connect it in nib file with your pickr.. – PJR Aug 17 '11 at 10:10
  • Building Successful :D , but it opens and closes a black screen in less then 1 sec – sillersam Aug 17 '11 at 10:23
  • i dont know but i am thinking there may be some other problem. hence first you have to understand what is delegate , controller and some basics dear.. – PJR Aug 17 '11 at 10:25
  • no i dont think you are getting problem with releasing effect? – PJR Aug 17 '11 at 10:34
  • ok can you make me a quick one and give me the source code , as i will appreciate it and give you a donation via paypal or alertpay :D – sillersam Aug 17 '11 at 10:36
  • there is a lot better, cleaner and framework-provided ways to do it. rather than animating the picker view then why should we go for workarounds? Its correct answer but not exactly right. see my answer here: http://stackoverflow.com/a/15218723/751026 – geekay Jun 29 '13 at 09:38
2

Well, you could rely on the UITextFieldDelegate to handle this kind of functionality.

Inside the

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField

is where you would set the text of your current UITextField as well as initializing and showing the UIPickerView.

Important notice:

You might also want to conform to the UIPickerViewDelegate.

HTH

Faizan S.
  • 8,634
  • 8
  • 34
  • 63
1

Swift:

internal var textFieldHandlerToolBar: UIToolbar = {
    let tb = UIToolbar.init(frame: CGRect.init(origin: .zero, size: CGSize.init(width: UIScreen.main.bounds.width, height: 44.0)))
    let doneBarButton = UIBarButtonItem.init(title: "Done", style: UIBarButtonItemStyle.done, target: self, action: #selector(actionDonePickerSelection))
    tb.setItems([doneBarButton], animated: false)
    return tb
}()

internal var pickerView: UIPickerView = {
    let pv = UIPickerView.init()
    return pv
}()

@objc internal func actionDonePickerSelection() {
     textField.resignFirstResponder()
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.pickerView.delegate = self
    self.pickerView.datasource = self
}

Use it like this:

textField.inputAccessoryView = self.textFieldHandlerToolBar
textField.inputView = self.pickerView
Hemang
  • 26,840
  • 19
  • 119
  • 186
0

http://tmblr.co/ZjkSZteCOUBS

I have the code and everything laid out in my blog to do this exactly. But below, I have the basic concept laid out.

Basically the solution involves an opensource project called ActionSheetPicker on github, and implementing the function textFieldShouldBeginEditing on the UITextFieldDelegate. You can dismiss the keyboard there and provide a UIPickerView instead. The basic code is listed here:

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
    // We are now showing the UIPickerViewer instead

    // Close the keypad if it is showing
    [self.superview endEditing:YES];

    // Function to show the picker view
    [self showPickerViewer :array :pickerTitle];

    // Return no so that no cursor is shown in the text box
    return  NO;
}
KVISH
  • 12,923
  • 17
  • 86
  • 162
  • Please note that you should post the useful points of an answer here, on this site, or your post risks being deleted as ["Not an Answer"](http://meta.stackexchange.com/q/8259). You may still include the link if you wish, but only as a 'reference'. The answer should stand on its own without needing the link. – Andrew Barber Nov 19 '12 at 20:01
0

ViewController.h

@interface ChangeCurrencyVC : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate>
{
      NSArray *availableCurreniesArray;
}
@property (weak, nonatomic) IBOutlet UITextField *chooseCurrencyTxtFldRef;

ViewController.m

 - (void)viewDidLoad {
[super viewDidLoad];
availableCurreniesArray = @[@"Indian Rupee", @"US Dollar", @"European Union Euro", @"Canadian Dollar", @"Australian Dollar", @"Singapore Dollar", @"British Pound", @"Japanese Yen"];
// Do any additional setup after loading the view.
[self pickerview:self];
}

 #pragma mark -  picker view Custom Method
 -(void)pickerview:(id)sender{
  UIPickerView *pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
pickerView.showsSelectionIndicator = YES;
pickerView.dataSource = self;
pickerView.delegate = self;

// set change the inputView (default is keyboard) to UIPickerView
self.chooseCurrencyTxtFldRef.inputView = pickerView;

// add a toolbar with Cancel & Done button
UIToolbar *toolBar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
toolBar.barStyle = UIBarStyleBlackOpaque;

UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:@selector(doneTouched:)];
UIBarButtonItem *cancelButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelTouched:)];
// the middle button is to make the Done button align to right
[toolBar setItems:[NSArray arrayWithObjects:cancelButton, [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil], doneButton, nil]];
self.chooseCurrencyTxtFldRef.inputAccessoryView = toolBar;
}
 #pragma mark - doneTouched
- (void)cancelTouched:(UIBarButtonItem *)sender{
// hide the picker view
[self.chooseCurrencyTxtFldRef resignFirstResponder];
 }
  #pragma mark - doneTouched
- (void)doneTouched:(UIBarButtonItem *)sender{
// hide the picker view
[self.chooseCurrencyTxtFldRef resignFirstResponder];
// perform some action
 }
#pragma mark - The Picker Challenge
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return [availableCurreniesArray count];
}
- (nullable NSString *)pickerView:(UIPickerView *)pickerView titleForRow: (NSInteger)row forComponent:(NSInteger)component{
return availableCurreniesArray[row];
}

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
self.chooseCurrencyTxtFldRef.text = availableCurreniesArray[row];
}
Mannam Brahmam
  • 2,225
  • 2
  • 24
  • 36
0

What you can do is, create a UIButton with custom type on UITextField. Both having equal sizes. On the touch of button you can show UIPickerView.

Nitish
  • 13,845
  • 28
  • 135
  • 263