Setting the title of current column in UITextField from UIPickerView? - ios

I have a UIPickerView that is being automatically loaded in loaded when a user touches the UITextField, at the end of selection the user can close the UIPicker by touching the "close" that I have added in the inputAccessoryView = toolbar;. My problem is that I need to set the value that is chosen in the UIPicker to be the value of self.textOutlet.text... I attempt to do so here but with no luck :
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [tempList objectAtIndex:row];
selectedText = _textOutlet.text;
Can someone please give me some ideas on how to fix this problem? Here is my header code:
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate>
#property (strong, nonatomic) NSString* selectedText; //the UITextField text
#property NSArray * tempList;
#end
And here is my implementation code:
#import "ViewController.h"
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UILabel *myLabel;
#property (weak, nonatomic) IBOutlet UIPickerView *thePicker;
#property (weak, nonatomic) IBOutlet UITextField *textOutlet;
#end
#implementation T3ViewController
#synthesize tempList, selectedText;
// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [tempList count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [tempList objectAtIndex:row];
selectedText = _textOutlet.text;
}
- (void)pickerView:(UIPickerView *)pickerView
didSelectRow:(NSInteger)row
inComponent:(NSInteger)component {
CGFloat chosenValue;
switch (row) {
case 0:
chosenValue = 0.0000233;
break;
case 1:
chosenValue = 0.0001273;
break;
case 2:
chosenValue = 0.0012333;
break;
case 3:
chosenValue = 0.0032204;
break;
case 4:
chosenValue = 0.0234179;
break;
case 5:
chosenValue = 0.0002369;
break;
case 6:
chosenValue = 0.0004442;
break;
default:
chosenValue = 0;
break;
}
NSNumberFormatter *formatter = [[NSNumberFormatter alloc]init];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
formatter.minimumFractionDigits=7;
self.myLabel.text = [formatter stringFromNumber:#(chosenValue)];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
tempList = [[NSArray alloc] initWithObjects:#"3222° F",#"22150° F",#"1260° F",#"12170° F",#"83210° F",#"84415° F",#"10120° F", nil];
// hides the picker upon initiation of the view
self.thePicker.hidden = YES;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(void)doneClicked:(id) sender
{
[_textOutlet resignFirstResponder]; //hides the pickerView
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
if (textField == self.textOutlet) {
self.textOutlet.inputView = _thePicker;
self.thePicker.hidden = NO;
UIToolbar* toolbar = [[UIToolbar alloc] init];
toolbar.barStyle = UIBarStyleBlackTranslucent;
[toolbar sizeToFit];
//to make the done button aligned to the right
UIBarButtonItem *flexibleSpaceLeft = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleDone target:self
action:#selector(doneClicked:)];
[toolbar setItems:[NSArray arrayWithObjects:flexibleSpaceLeft, doneButton, nil]];
self.textOutlet.inputAccessoryView = toolbar;
}
}
#end

In your first snippet of code, you are setting selectedText after the return statement. This line of code will never get executed.

You need to return AFTER setting the selectedText
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
selectedText = _textOutlet.text;
return [tempList objectAtIndex:row];

Related

Xcode Cocoa default picker animation not animating for iOS app

So I've followed everything this post Default Picker Value iphone says, but I can't seem to get my picker to work.
Here's my .m snippet:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.arrPercent = #[#"1",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9",#"10",#"11",#"12",#"13",#"14",#"15",#"16",#"17",#"18",#"19",#"20",#"21",#"22",#"23",#"24",#"25",#"26",#"27",#"28",#"29",#"30",#"31",#"32",#"33",#"34",#"35",#"36",#"37",#"38",#"39",#"40",#"41",#"42",#"43",#"44",#"45",#"46",#"47",#"48",#"49",#"50"];
self.arrPeople = #[#"1",#"2",#"3",#"4",#"5",#"6",#"7",#"8",#"9",#"10",#"11",#"12",#"13",#"14",#"15",#"16",#"17",#"18",#"19",#"20"];
self.percent = [NSNumber numberWithInt:15];
self.people = [NSNumber numberWithInt:5];
self.strSubTotal = #"";
self.myPicker.dataSource = self;
self.myPicker.delegate = self;
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
//[self.myPicker selectRow:self.percent.integerValue inComponent:0 animated:YES];
[self.myPicker selectRow:5 inComponent:0 animated:YES];
[self.myPicker selectRow:5 inComponent:1 animated:YES];
[self.myPicker reloadAllComponents]; // tried commenting out this line with no luck
}
Here's my .h snippet:
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
#interface ViewController : UIViewController <UIPickerViewDataSource,UIPickerViewDelegate>
#property (nonatomic,strong) NSArray *arrPercent;
#property (nonatomic,strong) NSArray *arrPeople;
#property (strong, nonatomic) IBOutlet UIPickerView *myPicker;
#property (strong, nonatomic) NSString *strSubTotal;
#property (strong, nonatomic) NSNumber *percent;
#property (strong, nonatomic) NSNumber *people;
#end
Here's the delegate stuff, I think...
// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent: (NSInteger)component
{
if(component== 0)
{
return [self.arrPercent count];
}
else
{
return [self.arrPeople count];
}
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if(component == 0)
{
return [NSString stringWithFormat:#"%#%#", [self.arrPercent objectAtIndex:row], #"%"];
}
else
{
return [self.arrPeople objectAtIndex:row];
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if(component == 0)
{
self.percent = [self.arrPercent objectAtIndex:row];
}
else
{
self.people = [self.arrPeople objectAtIndex:row];
}
[self updateSubTotal:-3];
}
When I start the emulator, the picker doesn't animate to the position I tell it to. Am I doing anything wrong? Please help!
As it turns out, the error was that for some reason, the connection between the picker in the UI was disconnected with the code. I had to hold the Control key while dragging the picker from the UI to the .h file.
I saw this because I noticed a little "empty button icon" next to the method declaration in the .h file. Once Xcode understood that the picker is controlled by the piece of code, everything works as expected.
Thank you so much!

EXC_BAD_ACCESS on UIPickerView - I need a bit of direction on why

I get the exc_bad_access error when running my project and trying to change the picker.
The error is occurring on
- (NSString*)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
Below is my code. From reading the other SO articles I realize I am probably not retaining my variable. I'm new and learning and appreciate the help.
#import <UIKit/UIKit.h>
#import "RootViewController.h"
#class RootViewController;
#interface AddConditionViewController : UIViewController <UIPickerViewDataSource, UIPickerViewDelegate> {
IBOutlet UITextField *txtConditionDetail;
IBOutlet UITextField *txtConditionArea;
IBOutlet UIPickerView *conditionNamesPicker;
NSMutableArray *names;
NSMutableArray *conditionDefs;
RootViewController *rvc;
NSString *conditionName;
}
#property (retain, nonatomic) IBOutlet UIPickerView *conditionNamesPicker;
#property (nonatomic,assign) RootViewController *rvc;
#property (nonatomic, retain) NSString *conditionName;
#property (nonatomic,assign) NSMutableArray *names;
#property (nonatomic,assign) NSMutableArray *conditionDefs;
#end
#import "AddConditionViewController.h"
#import "ConditionsAppDelegate.h"
#import "Condition.h"
#import "ConditionDef.h"
#import "Formula.h"
#implementation AddConditionViewController
#synthesize rvc, conditionNamesPicker, names, conditionDefs, conditionName;
/*
// Implement loadView to create a view hierarchy programmatically.
- (void)loadView {
}
*/
// Implement viewDidLoad to do additional setup after loading the view.
- (void)viewDidLoad {
[super viewDidLoad];
self.title = #"Add Condition";
self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemCancel
target:self action:#selector(cancel_Clicked:)] autorelease];
self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc]
initWithBarButtonSystemItem:UIBarButtonSystemItemSave
target:self action:#selector(save_Clicked:)] autorelease];
self.view.backgroundColor = [UIColor groupTableViewBackgroundColor];
ConditionsAppDelegate *appDelegate = (ConditionsAppDelegate *)[[UIApplication sharedApplication] delegate];
conditionDefs = appDelegate.getConditionDefs;
self.names = [NSMutableArray arrayWithCapacity:[conditionDefs count]];
for (ConditionDef *def in conditionDefs) {
NSString *condition_name = def.condition_name;
if (!condition_name) {
condition_name = #"<Unknown Account>";
}
[names addObject:condition_name];
}
self.conditionNamesPicker.dataSource = self;
self.conditionNamesPicker.delegate = self;
NSLog(#"LINE 48");
}
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
//Set the textboxes to empty string.
txtConditionArea.text = #"";
txtConditionDetail.text = #"";
//Make the Category name textfield to be the first responder.
[txtConditionArea becomeFirstResponder];
NSLog(#"LINE 63");
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview
// Release anything that's not essential, such as cached data
}
// The number of columns of data
- (int)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
// The number of rows of data
- (int)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
NSLog(#" LINE 87 - COUNT OF CONDITION DEFS TO SHOW = %i", names.count);
[conditionNamesPicker setDataSource:self];
return [names count];
}
// The data to return for the row and component (column) that's being passed in
- (NSString*)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
// NSLog(#"LINE 94 - here is the bug: conditionDefs[row] %#", names[row]);
return names[row];
}
// Catpure the picker view selection
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// This method is triggered whenever the user makes a change to the picker selection.
// The parameter named row and component represents what was selected.
conditionName = names[row];
}
- (void) save_Clicked:(id)sender {
ConditionsAppDelegate *appDelegate = (ConditionsAppDelegate *)[[UIApplication sharedApplication] delegate];
//Create a Condition Object.
Condition *c = [[Condition alloc] init];
NSInteger newId = c.getNextConditionId;
Condition *cond = [[Condition alloc] initWithPrimaryKey:newId];
cond.condition_area = txtConditionArea.text;
cond.condition_detail = txtConditionDetail.text;
cond.condition_name = conditionName;
//Add the object
// [appDelegate addCondition:cond];
[appDelegate populateFromDatabase];
// ADD TO THE ARRAY:
// [cvc.categories addObject:cond];
// [cvc.Conditions addObject:cond];
rvc.Conditions = [appDelegate activeConditions];
// UPDATE THE TABLEVIEW
[rvc.tableView reloadData];
// release
[cond release];
[c release];
//Dismiss the controller.
[self.navigationController dismissViewControllerAnimated:YES completion: nil];
}
- (void) cancel_Clicked:(id)sender {
//Dismiss the controller.
[self.navigationController dismissViewControllerAnimated:YES completion: nil];
}
- (BOOL)textFieldShouldReturn:(UITextField *)theTextField {
NSLog(#"LINE 159");
[theTextField resignFirstResponder];
return YES;
}
- (void)dealloc {
[txtConditionArea release];
[txtConditionDetail release];
[conditionNamesPicker release];
[super dealloc];
}
#end
Please change the property assign toretain for names property. And other array or those object inheriting fromNSObject. It is an object and you are keeping it as assign property. Use assign only for primitive data type. Try this and let me know.
You are setting the data source of PickerView in one the DataSource methods. This is not valid. Remove the below line
[conditionNamesPicker setDataSource:self];
from function:
numberOfRowsInComponent:
You are setting it again.

PickerView is not showing

I'm trying to bring up a picker view instead of a keyboard to put in a textfield, but my picker view doesn't show.
#import "SettingsViewController.h"
#import "FindClasses.h"
#interface SettingsViewController ()
#property (weak, nonatomic) IBOutlet UIBarButtonItem *saveButton;
#property (weak, nonatomic) IBOutlet UITextField *classTextField;
#property (strong, nonatomic) UIPickerView *picker;
#property (nonatomic, strong) FindClasses *finder;
#property (nonatomic, strong) NSArray *itemsArray;
#end
#implementation SettingsViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSArray *itemsArray = [self.finder findClassesInTimetable];
// Do any additional setup after loading the view.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)presentPicker {
CGRect frame = CGRectMake(0, 40, 0, 0);
UIPickerView *picker = [[UIPickerView alloc] initWithFrame:frame];
picker.delegate = self;
picker.dataSource = self;
// TODO: animate this on screen
[self.view addSubview:picker];
}
- (void)textFieldDidBeginEditing:(UITextField *)textField {
[self presentPicker];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [self.itemsArray count]; //where items is your array of items
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row inComponent:(NSInteger)component {
return [self.itemsArray objectAtIndex:row];
}
Can someone tell me what I'm doing wrong? I took the example from another Stackoverflow post:
This is how I use UIPickerViews, with sample code:
UIPickerView* genderPicker = [[UIPickerView alloc] init];
genderPicker.delegate = self;
genderPicker.dataSource = self;
After initializing your UITextField (registrationGenderField in my case):
registrationGenderField.inputView = genderPicker;
And then the delegates and dataSources:
- (NSString *) pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component {
switch (row) {
case 0:
return #"Gender";
break;
case 1:
return #"Male";
break;
case 2:
return #"Female";
break;
default:
return #"Gender";
break;
}
}
- (void) pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
switch (row) {
case 0:
registrationGenderField.text = #"";
break;
case 1:
registrationGenderField.text = #"Male";
break;
case 2:
registrationGenderField.text = #"Female";
break;
default:
registrationGenderField.text = #"";
break;
}
}
- (NSInteger) numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSInteger) pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return 3;
}
Hope it helps you
- (void)presentPicker {
UIPickerView *picker = [[UIPickerView alloc] init];
picker.delegate = self;
picker.dataSource = self;
// TODO: animate this on screen
classTextField .delegate = self;
classTextField.inputView = picker;
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField {
[textField becomeFirstResponder];
return YES;
}
you just have to alloc init your pickerview;
and set its delegate to self and also add uipickerviewdelegate and datasource in .h file
than in textfieldbegin editing add [textField setInputView:picker];
also implement textfieldshouldreturn

Base IBAction of Button Item on Title of Other Button Item

Hopefully this is an easy one.
Here's the deal: I've got a button item, "Select", that opens a picker. When the user selects something from the picker, the title of "Select" button changes to the selection and the picker animates out of view. Now I've created a second "Search" button that will query the Google Places API, but I need it to NOT query ITS title as its doing now, but the title of the OTHER button. Make sense?
This is the relevant code. I'm positive it's a simple tweak, but I'm new to Objective-C, so I'm still wrapping my head around how things operate.
ViewController.m
#import "RendezvousViewController.h"
#interface RendezvousViewController ()
#end
#implementation RendezvousViewController
// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [self.userSelectArray count];
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [self.userSelectArray objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSLog(#"Selected Row %ld", (long)row);
switch(row)
{
case 0:
self.userSelection.title = #"Breakfast";
break;
case 1:
self.userSelection.title = #"Brunch";
break;
case 2:
self.userSelection.title = #"Lunch";
break;
case 3:
self.userSelection.title = #"Dinner";
break;
case 4:
self.userSelection.title = #"Bar";
break;
case 5:
self.userSelection.title = #"Late Night Snack";
break;
}
}
-(void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.userSelectArray = [[NSArray alloc] initWithObjects:#"Breakfast",#"Brunch",#"Lunch",#"Dinner",#"Bar",#"Late Night Snack" , nil];
//Make this controller the delegate for the map view.
self.mapView.delegate = self;
// Ensure that you can view your own location in the map view.
[self.mapView setShowsUserLocation:YES];
//Instantiate a location object.
locationManager = [[CLLocationManager alloc] init];
//Make this controller the delegate for the location manager.
[locationManager setDelegate:self];
//Set some parameters for the location object.
[locationManager setDistanceFilter:kCLDistanceFilterNone];
[locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
firstLaunch=YES;
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)toolbarButtonPress:(id)sender {
UIBarButtonItem *button = (UIBarButtonItem *)sender;
NSString *buttonTitle = [button.title lowercaseString];
[self queryGooglePlaces:buttonTitle];
//Use the above title text to build the URL query and get the data from Google.
}
ViewController.m
#interface RendezvousViewController : UIViewController <MKMapViewDelegate, CLLocationManagerDelegate, UIPickerViewDataSource,UIPickerViewDelegate>
{
CLLocationManager *locationManager;
CLLocationCoordinate2D currentCentre;
int currenDist;
BOOL firstLaunch;
}
#property (strong, nonatomic) IBOutlet MKMapView *mapView;
#property (strong, nonatomic) IBOutlet UIBarButtonItem *userSelection;
#property (strong, nonatomic) IBOutlet UIBarButtonItem *searchButton;
#property (strong, nonatomic) IBOutlet UIPickerView *userPicker;
#property (strong, nonatomic) NSArray *userSelectArray;
#end
As always, thanks in advance.
If you make the button a property on your view, you could just access it directly (instead of using sender).
But why not get it directly from the picker instead of indirectly from the button title?
EDIT:
So based on your code, you want to add another button
#implementation RendezvousViewController{
UIButton *selectButton;
}
Initalize it
-(void)viewDidLoad {
selectButton = [[UIButton alloc] init];
...
}
Then set the title in the picker
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSLog(#"Selected Row %ld", (long)row);
switch(row)
{
case 0:
self.selectButton.title = #"Breakfast";
break;
...
}
}
Then grab it when your other button is selected:
- (IBAction)toolbarButtonPress:(id)sender {
NSString *buttonTitle = [self.selectButton.title lowercaseString];
[self queryGooglePlaces:buttonTitle];
//Use the above title text to build the URL query and get the data from Google.
}
#implementation RendezvousViewController{
UIButton *selectButton;
NSString *selection;
}
I would suggest however, to have another property to just store the value that was selected instead of relying on your UI, like the button title. It would look like this:
Initalize it
-(void)viewDidLoad {
selectButton = [[UIButton alloc] init];
selection = #"";
...
}
Then set the title in the picker
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
NSLog(#"Selected Row %ld", (long)row);
switch(row)
{
case 0:
selection = #"Breakfast";
break;
...
}
self.selectButton.title = selection;
}
Then grab it when your other button is selected:
- (IBAction)toolbarButtonPress:(id)sender {
[self queryGooglePlaces:selection];
//Use the above title text to build the URL query and get the data from Google.
}
if([buttonTitle isEqualToString:"Select"])
return; //no searching
else{
[self queryGooglePlaces:buttonTitle];
}

UIPickerView doesn't appear

In a ViewController call by push, I try to programmatically display a ComboBox. This combobox implement UIPickerView delegate protocol and add a .xib file.
When i run the app, i can see my combobox on the screen, but when i click on it, nothing append. Normally the pickerview will be displayed.
What i don't understand, is in another viewcontroller call modal it works fine
//
// ComboBox.h
//
#import <UIKit/UIKit.h>
#interface ComboBox : UIViewController<UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate>
{
UIPickerView* pickerView;
IBOutlet UITextField* textField;
NSMutableArray *dataArray;
}
-(void) setComboData:(NSMutableArray*) data; //set the picker view items
-(void) setPlaceholder:(NSString*) label;
#property (retain, nonatomic) NSString* selectedText; //the UITextField text
#property (retain, nonatomic) IBOutlet UITextField* textField; //the UITextField
#end
//
// ComboBox.m
//
#import "ComboBox.h"
#implementation ComboBox
#synthesize selectedText;
#synthesize textField;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
return [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
}
- (void)viewDidUnload
{
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
//-- UIPickerViewDelegate, UIPickerViewDataSource
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
{
return 1;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
textField.text = [dataArray objectAtIndex:row];
selectedText = textField.text;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
{
return [dataArray count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
return [dataArray objectAtIndex:row];
}
//-- ComboBox
-(void) setComboData:(NSMutableArray*) data
{
dataArray = data;
}
-(void) setPlaceholder:(NSString *)label
{
textField.placeholder = label;
}
-(void)doneClicked:(id) sender
{
[textField resignFirstResponder]; //hides the pickerView
}
- (IBAction)showPicker:(id)sender {
pickerView = [[UIPickerView alloc] init];
pickerView.showsSelectionIndicator = YES;
pickerView.dataSource = self;
pickerView.delegate = self;
UIToolbar* toolbar = [[UIToolbar alloc] init];
toolbar.barStyle = UIBarStyleBlackTranslucent;
[toolbar sizeToFit];
//to make the done button aligned to the right
UIBarButtonItem *flexibleSpaceLeft = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleDone target:self
action:#selector(doneClicked:)];
[toolbar setItems:[NSArray arrayWithObjects:flexibleSpaceLeft, doneButton, nil]];
//custom input view
textField.inputView = pickerView;
textField.inputAccessoryView = toolbar;
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)aTextField
{
[self showPicker:aTextField];
return YES;
}
#end
the viewdidload of my viewcontroller
- (void)viewDidLoad
{
[super viewDidLoad];
NSMutableArray* ServeurArray = [[NSMutableArray alloc] init];
[ServeurArray addObject:#"1"];
[ServeurArray addObject:#"2"];
[ServeurArray addObject:#"3"];
comboServeur = [[ComboBox alloc] init];
[comboServeur setComboData:ServeurArray]; //Assign the array to ComboBox
comboServeur.view.frame = CGRectMake(95, 220, 130, 31); //ComboBox location and size (x,y,width,height)
[self.view addSubview:comboServeur.view];
}
thx for your answers
I assume that you are targeting iOS 5.0 and above. Since you are adding a view of a viewController to another viewController you can use the childViewController introduced in iOS 5.0.
Modify your viewDidLoad method
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
ComboBox *comboServeur = [[ComboBox alloc]initWithNibName:#"ComboBoxController" bundle:nil];
[comboServeur setComboData:#[#"1",#"2",#"3"]];
comboServeur.view.frame = CGRectMake(50.0f, 200.0f, 220.0f, 31.0f);
[self.view addSubview:comboServeur.view];
[self addChildViewController:comboServeur];
[comboServeur didMoveToParentViewController:self];
}
Few steps to check
Make the view of the ComboBox viewController freeform with maskType UIViewAutoresizingNone.
Check the textField and delegate of textField is connected
Demo project
I forget the specifics but I remember having the same problem but the thing for me was that I needed to link it to delegate or datasource or something? I'm not 100% sure since it's been quite a while but make sure when you have it on your view you link it to your picker reference + the other thing that you need.
Your ComboBox class isn't set as a delegate for the UITextField, so textFieldShouldBeginEditing: will never be called.
i try to use this combo class in my viewcontroller, i try all the solution you give to me, but nothing work, so the solution is to implement all the combo class code directly in my viewcontroller, and now it works, but it's a little bit uggly...

Resources