I am working on a UIPickerController. I have everything working but when I tap the back button to go to my previous view the app is crashing.
I am thinking it could be catching a memory leak.
Here is my code. If anyone sees something I have missed or may have a clue on what cause this please inform me. Nothing displays in the Debugger.
#synthesize colorTextField, pickerView, pickerToolbar;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)dealloc
{
[colorTextField release];
[pickerView release];
[pickerToolbar release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidLoad
{
[super viewDidLoad];
colorsArray = [[NSMutableArray alloc] init];
[colorsArray addObject:#"Red"];
[colorsArray addObject:#"Orange"];
[colorsArray addObject:#"Yellow"];
[colorsArray addObject:#"Green"];
[colorsArray addObject:#"Blue"];
[colorsArray addObject:#"Indigo"];
[colorsArray addObject:#"Violet"];
}
- (void)setColor
{
actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:nil cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil];
[actionSheet setActionSheetStyle:UIActionSheetStyleBlackTranslucent];
CGRect pickerFrame = CGRectMake(0, 40, 0, 0);
pickerView = [[UIPickerView alloc] initWithFrame:pickerFrame];
pickerView.showsSelectionIndicator = YES;
pickerView.dataSource = self;
pickerView.delegate = self;
[actionSheet addSubview:pickerView];
[pickerView release];
pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, actionSheet.bounds.size.width, 44)];
[pickerToolbar setBarStyle:UIBarStyleBlack];
[pickerToolbar sizeToFit];
UIBarButtonItem* doneButton = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(pickerDoneClicked)];
[pickerToolbar setItems:[NSArray arrayWithObject:doneButton] animated:NO];
[doneButton release];
[actionSheet addSubview:pickerToolbar];
[pickerToolbar release];
[actionSheet showInView:self.view];
[actionSheet setBounds:CGRectMake(0, 0, 320, 485)];
}
- (void)pickerDoneClicked
{
[actionSheet dismissWithClickedButtonIndex:0 animated:YES];
[actionSheet release];
}
- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField
{
[self setColor];
return NO;
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [colorsArray count];
}
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [colorsArray objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSLog(#"Selected Color: %#. Index of selected color: %i", [colorsArray objectAtIndex:row], row);
[colorTextField setText:(NSString *)[colorsArray objectAtIndex:row]];
}
- (void)viewDidUnload
{
[self setColorTextField:nil];
[super viewDidUnload];
}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
#end
You're double-releasing pickerView and pickerToolbar, once in setColor and again in dealloc.
A good pattern when releasing views held in ivars is to set the ivar to nil after releasing the view, this will prevent double-releases.
I think your release some of your items mor ethan once
EG:
in the dealloc you have two
[pickerView release];
[pickerToolbar release];
that are release already
eg:
[actionSheet addSubview:pickerView];
[pickerView release];
so it has nothing to release me thinks, so remove the duplicate releases??
Related
I am trying to prevent my UIPickerview from closing when a field is selected by a user. I want the user to be able to select a field without UIPickerview dismissing automatically. I have tried so many things such as trying the following but none of them helped:
_txtfield.hidden=NO;
[_pickerView endEditing:NO];
[pickerView endEditing:NO];
[_txtfield endEditing:NO];
[self endEditing:NO];
_pickerView.hidden=NO;
-----------------Here is more code----------------
#implementation FieldWithPickerView {
void(^pickerCallback)(NSInteger row);
CGRect myFrame;
}
-(void)viewDidAppear{
}
-(void)commonInit:(CGRect)frame{
[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:self options:nil];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|[view]|" options:0 metrics:nil views:#{#"view":self.InputViewPicker}]];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[view]|" options:0 metrics:nil views:#{#"view":self.InputViewPicker}]];
[self.layer setCornerRadius:10.0f];
[self setClipsToBounds:YES];
_pickerView = [[UIPickerView alloc] init];
_pickerView.delegate=self;
UIToolbar *toolBar=[[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, 320, 44)];
[toolBar setTintColor:[UIColor grayColor]];
UIBarButtonItem *doneBtn=[[UIBarButtonItem alloc]initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(removePicker)];
UIBarButtonItem *space=[[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
[toolBar setItems:[NSArray arrayWithObjects:space,doneBtn, nil]];
[self.txtfield setInputAccessoryView:toolBar];
self.txtfield.inputView = _pickerView;
[_txtfield.inputView setBackgroundColor:[UIColor clearColor]];
[_txtfield setBackgroundColor:[UIColor clearColor]];
_txtfield.text=#"--Select---";
_label_view.textColor=[UIColor whiteColor];
_label_view.backgroundColor=SECURUSBLUE;
_label_view.textAlignment = NSTextAlignmentCenter;
_txtfield.textAlignment = NSTextAlignmentCenter;
}
-(void)removePicker
{
[_txtfield resignFirstResponder];
}
-(void)pickerListenner:(void(^)(NSInteger row))handler
{
pickerCallback=handler;
}
- (id)initWithFrame:(CGRect)frame
{
// NSLog(#"initwithframe picker");
self = [super initWithFrame:frame];
if (self)
{
[self commonInit:frame];
}
return self;
}
#pragma mark - Picker View Data source
- (NSInteger)numberOfComponentsInPickerView:
(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
return [_pickerData count];;
}
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
if(_pickerData.count == 0)
return #"There is nothing";
return [_pickerData objectAtIndex:row];
}
#pragma mark -
#pragma mark - UIPickerViewDelegate
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
// Code logic
NSLog(#"selected row --->%ld!!!!",(long)row);
pickerCallback(row);
// _txtfield.text=[_pickerData objectAtIndex:row];
_txtfield.hidden=NO;
}
- (NSInteger)selectedRowInComponent:(NSInteger)component
{
return component;
}
You need to implement the UIPickerView delegate methods, so add <UIPickerViewDelegate> to your ViewController.
in your viewDidLoad method conform to the protocol like so:
pickerView.delegate = self;
Then add the following method to detect when a row has been selected:
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
// do nothing because it will not dismiss
}
You will need to implement the numberOfRowsInComponent, numberOfComponents, and titleForRow delegate methods as well, but once those are implemented your picker view should not dismiss when a row is selected. You will need to manually dismiss the picker view in your didSelectRow delegate method.
I'm a beginner in iOS Objective-C programming so first of all - sorry for being silly.
I'm using UIPickerView to fill UITextField and it works perfectly for the first use.
photo
Lets assume that user made a mistake using pickerview for the first time. He wants to correct this and opens the same pickerview again. Pickerview is empty.
photo
Also okayButton is missing. What am I doing wrong?
Here's my code:
#import "LoginViewController.h"
#interface LoginViewController ()
#end
#implementation LoginViewController
- (void)viewDidLoad {
[super viewDidLoad];
marksArray =[[NSMutableArray alloc] init];
fuelTypeArray =[[NSMutableArray alloc] init];
inputArray =[[NSMutableArray alloc] init];
marksArray = [NSMutableArray arrayWithObjects:#"Alfa Romeo", #"Aston Martin", #"BMW", #"Cadillac", #"Chevrolet", #"Chrysler", #"Citroen", #"Dacia", #"Daewoo", #"Dodge", #"Ferrari", #"Ford", #"Honda", #"Hummer", #"Hyundai", #"Infiniti", #"Jaguar", #"Jeep", #"Kia", #"Lamborghini", #"Lancia", #"Land Rover", #"Lexus", #"Maserati", #"Mazda", #"Mercedes-Benz", #"Mini", #"Mitsubishi", #"Nissan", #"Opel", #"Peugeot", #"Polonez", #"Pontiac", #"Porshe", #"Renault", #"Rover", #"Saab", #"Seat", #"Skoda", #"Smart", #"Subaru", #"Suzuki", #"Toyota", #"Volkswagen", #"Volvo", nil];
fuelTypeArray = [NSMutableArray arrayWithObjects:#"Benzyna", #"Benzyna+LPG", #"Diesel", #"Elektryczny", #"Hybryda", nil];
okayImageView.hidden = true;
okayButton.hidden= true;
//makes fuelTypePickerView as input console for markTextField
fuelTypePickerView.hidden = true;
fuelTypePickerView = [[UIPickerView alloc] init];
fuelTypePickerView.delegate = self;
fuelTypePickerView.showsSelectionIndicator = YES;
fuelTypeTextField.inputView = fuelTypePickerView;
//makes markPickerView as input console for markTextField
markPickerView.hidden = true;
markPickerView = [[UIPickerView alloc] init];
markPickerView.delegate = self;
markPickerView.showsSelectionIndicator = YES;
markTextField.inputView = markPickerView;
// scrolling login view controller
[scroller setScrollEnabled:YES];
[scroller setContentSize:CGSizeMake(320, 615)];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// returns the number of 'columns' to display.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
okayImageView.hidden = false;
okayButton.hidden= false;
return 1;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
if([pickerView isEqual: markPickerView]){
return 45;
}else if([pickerView isEqual: fuelTypePickerView]){
return 5;
}else{
return 0;
}
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
if([pickerView isEqual: markPickerView]){
self->inputArray = self->marksArray;
return inputArray[row];
}else if([pickerView isEqual: fuelTypePickerView]){
self->inputArray = self->fuelTypeArray;
return inputArray[row];
}else{
return 0;
}
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if([pickerView isEqual: markPickerView]){
markTextField.text = [inputArray objectAtIndex:row];
}else if([pickerView isEqual: fuelTypePickerView]){
fuelTypeTextField.text = [inputArray objectAtIndex:row];
}
}
-(IBAction) okayButtonPressed:(id)sender{
if(markPickerView.hidden!=YES){
okayImageView.hidden = true;
okayButton.hidden= true;
markPickerView.hidden=YES;
[markTextField resignFirstResponder];
}else if(fuelTypePickerView.hidden!=YES){
okayImageView.hidden = true;
okayButton.hidden= true;
fuelTypePickerView.hidden=YES;
[fuelTypeTextField resignFirstResponder];
}
}
#end
Thanks!
Try adding the following lines in your code
#interface LoginViewController () <UITextFieldDelegate>
then in viewDidLoad
fuelTypeTextField.delegate = self;
markTextField.delegate = self;
Now implement UITextField Delegate in your LoginViewController
-(void)textFieldDidBeginEditing:(UITextField *)sender{
okayImageView.hidden = NO;
okayButton.hidden = NO;
if([sender isEqual:fuelTypeTextField])
{
fuelTypePickerView.hidden = NO;
}
else{
markPickerView.hidden = NO;
}
}
In your Code after click on OK button you are hiding the PickerView, ImageView and Button. But on next time editing the textField you are not unhiding them thats why they are not shown.
I have created a text field that upon entry will open a picker view with a toolbar that contains a done button. However, when the done button is pressed the picker view doesn't dismiss. Everything else works just as I want except this. I've tried several options to no avail. Please review and let me know what I'm missing.
My code is below:
ViewController.h
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController
{IBOutlet UITextField *productDescription; IBOutlet UIPickerView *productPicker; NSArray *productListArray}
ViewController.m
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
-(void)addPickerView{
productListArray = [[NSArray alloc]initWithObjects:
#"myArray", nil];
productDescription.delegate = self;
[self.view addSubview:productDescription];
[productDescription setPlaceholder:#"Product Description"];
productPicker = [[UIPickerView alloc]init];
productPicker.dataSource = self;
productPicker.delegate = self;
productPicker.showsSelectionIndicator = YES;
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc]
initWithTitle:#"Done" style:UIBarButtonItemStyleDone
target:self action:#selector(resignFirstResponder)];
UIToolbar *toolBar = [[UIToolbar alloc]initWithFrame:
CGRectMake(50, 320, 50, 50)];
[toolBar setBarStyle:UIBarStyleBlackOpaque];
NSArray *toolbarItems = [NSArray arrayWithObjects:
doneButton, nil];
[toolBar setItems:toolbarItems];
productDescription.inputView = productPicker;
productDescription.inputAccessoryView = toolBar;
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self addPickerView];
}
#pragma mark - Text field delegates
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
([textField.text isEqualToString:#""]);
}
#pragma mark - Picker View Data source
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component{
return [productListArray count];
}
#pragma mark- Picker View Delegate
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:
(NSInteger)row inComponent:(NSInteger)component{
[productDescription setText:[productListArray objectAtIndex:row]];
}
- (void)doneButton:(UIBarButtonItem *)sender{
NSLog(#"Done Touched");
[productPicker setHidden:YES];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:
(NSInteger)row forComponent:(NSInteger)component{
return [productListArray objectAtIndex:row];
}
#end
.M File
Xib file in take Textfield and set delegate with connect.
#import "YourViewController.h"
#interface YourViewController ()<UIPickerViewDataSource,UIPickerViewDelegate>
{
UIPickerView *productPicker;
NSArray *productListArray;
IBOutlet UITextField *productDescription;
}
#end
- (void)viewDidLoad
{
[super viewDidLoad];
[self addPickerView];
}
-(void)addPickerView
{
productListArray = [[NSArray alloc]initWithObjects:#"myArray",#"Rohit",#"Change",#"Your view", nil];
[productDescription setPlaceholder:#"Product Description"];
productPicker = [[UIPickerView alloc]init];
productPicker.dataSource = self;
productPicker.delegate = self;
productPicker.showsSelectionIndicator = YES;
UIToolbar* toolBar = [[UIToolbar alloc] init];
toolBar.barStyle = UIBarStyleBlack;
toolBar.translucent = YES;
toolBar.tintColor = nil;
[toolBar sizeToFit];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc]initWithTitle:#"Done" style:UIBarButtonItemStyleDone target:self action:#selector(doneButton:)];
[toolBar setItems:[NSArray arrayWithObjects:doneButton, nil]];
productDescription.inputView = productPicker;
productDescription.inputAccessoryView = toolBar;
}
- (IBAction)doneButton:(id)sender
{
NSLog(#"Done Touched");
[productPicker removeFromSuperview];
[productPicker resignFirstResponder];
[self.view endEditing:YES];
}
#pragma mark - Text field delegates
- (void)textFieldDidBeginEditing:(UITextField *)textField {
productDescription.inputView = productPicker;
}
#pragma mark - Text field delegates
- (void)textFieldDidBeginEditing:(UITextField *)textField {
productDescription.inputView = productPicker;
}
#pragma mark - Picker View Data source
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component{
return [productListArray count];
}
#pragma mark- Picker View Delegate
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component{
[productDescription setText:[productListArray objectAtIndex:row]];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component{
return [productListArray objectAtIndex:row];
}
I hope this will help you great.
I have a UIPickerView that is being "pushed" to UINavigationController like this:
[self.navigationController pushViewController:vc animated:YES];
I would like to set the selected row.
I added in ViewDidAppear:
for (int i = 0; i < [countryCodes count]; i++)
{
if ([[countryCodes objectAtIndex:i] isEqualToString:selectedCountryCode]){
[_countryPicker selectRow:i inComponent:0 animated:YES];
countrySelectedRow = i;
break;
}
}
[_countryPicker reloadAllComponents];
where i is dynamic (being changed based on data that is changing in that view controller)
It works only if I restart the app.
If I go back and forth in the navigation it doesn't work
How can I make the UIPickerView choose the the correct row?
I can see in debug mode that the lines in viewDidAppear are called. Maybe the component is being created and I can't change it?
This is how I create the UIPickerView:
- (void)viewDidLoad
{
_countryPicker = [[UIPickerView alloc] init];
[self initPicker:_countryPicker textField:_countryText];
}
- (void)initPicker:(UIPickerView*)pickerView textField:(UITextField*) textField
{
CGRect pickerFrame = CGRectMake(0, 0, 200, 216);
pickerView.frame = pickerFrame;
pickerView.userInteractionEnabled = YES;
pickerView.dataSource = self;
pickerView.hidden = YES;
pickerView.delegate = self;
pickerView.showsSelectionIndicator = YES;
[self.view addSubview:pickerView];
[textField setInputView:pickerView];
textField.delegate = self;
[pickerView removeFromSuperview];
}
You wrote: "where i is dynamic (being changed based on data that is changing in that view controller)""
In your code i is a local variable. Did you mean selectedCountryCode here?
for (int i = 0; i < [countryCodes count]; i++)
{
if ([[countryCodes objectAtIndex:i] isEqualToString:selectedCountryCode]){
[_countryPicker selectRow:i inComponent:0 animated:YES];
countrySelectedRow = i;
break;
}
}
[_countryPicker reloadAllComponents];
I am pretty sure selectedCountryCode is not updated correctly. Add NSLog(selectedCountryCode); to check it.
UPDATE:
It seems that problem is somewhere inside a code you did not post in the question. To check your code I created and share a project. Please find it here https://github.com/Avtolic/SOHelper If you will check it you will find that everything works ok.
After you set the selected row you then call this...
[_countryPicker reloadAllComponents];
Thats going to wipe out your selection? I would remove that line
If you make the selectedCountryCode variable part of a singleton class (for example AppDelegate or preferebly some other), and then equate the value, this is surely going to work. Here I don't understand how the selectedCountryCode is expected to be retained even after the view is popped.
I tried with making the string a part of AppDelegate (which is of course not a good practice. One should put it in another singleton class).
#import "CViewController.h"
#import "AppDelegate.h"
#interface CViewController ()<UITextFieldDelegate, UIPickerViewDelegate, UIPickerViewDataSource>
#property(nonatomic, strong) UIPickerView *countryPicker;
#property (nonatomic, weak) IBOutlet UITextField *countryText;
#property (nonatomic, strong) NSArray *countryCodes;
#property (nonatomic, assign) int countrySelectedRow;
#property (nonatomic,strong) AppDelegate *delegate;
#end
#implementation CViewController
- (void)viewDidLoad
{
self.delegate = [[UIApplication sharedApplication] delegate];
_countryPicker = [[UIPickerView alloc] init];
[self initPicker:_countryPicker textField:_countryText];
self.countryCodes = #[#"A", #"B", #"C", #"D", #"E"];
}
- (void)initPicker:(UIPickerView*)pickerView textField:(UITextField*) textField
{
CGRect pickerFrame = CGRectMake(0, 0, 200, 216);
pickerView.frame = pickerFrame;
pickerView.userInteractionEnabled = YES;
pickerView.dataSource = self;
pickerView.hidden = YES;
pickerView.delegate = self;
pickerView.showsSelectionIndicator = YES;
[self.view addSubview:pickerView];
[textField setInputView:pickerView];
textField.delegate = self;
[pickerView removeFromSuperview];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
return [self.countryCodes objectAtIndex:row];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
// returns the # of rows in each component..
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
return [self.countryCodes count];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
self.delegate.selectedCountryCode = [self.countryCodes objectAtIndex:row];
NSLog(#"picker was(is): %d",[_countryPicker selectedRowInComponent:0]);
}
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
for (int i = 0; i < [self.countryCodes count]; i++)
{
if ([[self.countryCodes objectAtIndex:i] isEqualToString:self.delegate.selectedCountryCode]){
[_countryPicker selectRow:i inComponent:0 animated:YES];
self.countrySelectedRow = i;
break;
}
}
[_countryPicker reloadAllComponents];
}
-(void)textFieldDidBeginEditing:(UITextField *)textField
{
self.countryPicker.hidden = NO;
}
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...