Recently we had to create a registration form which allows you to set some different data like country, language, first and last name, date of birth, etc. It’s not a problem to edit text-like properties. All you need is to create a UITextField. Everything else is done automatically. When a text field gets a focus (or becomes a first responder – using iPhone‘s language) a keyboard panel appears at the bottom and you can change the field’s content.
But for some other fields – I’d like them to behave like combo boxes. Instead of typing the whole name of a country I prefer to select it from the list. Cocoa Touch framework doesn’t have a combo box – known from desktop apps – but it has something called UIPickerView. A UIPickerView is in fact a kind of combo box adopted to a multitouch device. So is UIDatePicker. The problem I faced using iPhone’s pickers was how to link them to the text fields. I found a hacky solution which consists in using a UIButton instead of UITextField and showing up a picker manually when the button is tapped. But there is much better and proper solution – inputView.
InputView is a property of UIResponder class – so also of UITextFiled class. When you set it to any custom view that view will appear any time your control becomes a first responder. Cool and smooth solution, isn’t it?
Below is a a piece of code of hooking up a UIPickerView to the UITextField.
UIPickerView *countryPicker = [[UIPickerView alloc] initWithFrame:CGRectZero];
countryPicker.delegate = self;
countryPicker.dataSource = self;
[countryPicker setShowsSelectionIndicator:YES];
countryTextField.inputView = countryPicker;
[countryPicker release];
It’s all you need to show up a UIPickerView when you tap on a text field. Handling picker’s delegates is very easy.
For the UIPickerViewDataSource you just need to give a number of rows and columns of the picker view.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return countries.count;
}
UIPickerViewDelegate is used to:
- tell the control what values should be displyed at each row/column
- update the text field with already selected value
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [countries objectAtIndex:row];
}
- (void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
countryTextField.text = (NSString *)[countries objectAtIndex:row];
}
Of course you can assign your custom view not only to UITextField objects but also to other UIControl-derived objects (UIControl inherits from UIView and UIView from UIResponder).
If you want to use the inputView property with buttons you have to create a new class that derives from UIButton, make inputView property writable and override canBecomeFirstResponder method (see the code below).
Header file
@interface CustomButton : UIButton
{
UIView *_inputView;
}
@property (nonatomic, retain) UIView *inputView;
@end
Source file
#import "CustomButton.h"
@implementation CustomButton
@synthesize inputView = _inputView;
- (BOOL) canBecomeFirstResponder
{
return YES;
}
@end
Tip:
If you wonder how to display a toolbar or any other view above your keyboard or picker (see picture above) then have a look at inputAccessoryView – another property of UIResponder class. It works exactly the same as the inputView.
The sample code for this article can be found here.
-
Robbie
-
http://rodliberal.com Rod
-
Pawel
-
-
http://yasirmturk.com Yasir M Turk
-
Pawel
-
-
http://www.stewartmacdonald.com.au Stewart Macdonald
-
http://chrisjones.id.au Christopher Jones
-
Stine
-
Stine Søndergaard
-
http://chrisjones.id.au Christopher Jones
-
Ben
-
rahul


