UIpicker array with changing values - iphone

I'm making an app that uses the picker to let the user pick age and few other inputs. for eg: i have a button age, when the user clicks it, the picker shows the age. i managed to add individual picker for all the inputs, how ever i'm having problems setting different arrays for each picker.
- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if (pickerview == picker) {
return [pickerViewArray objectAtIndex:row];
}
else if (pickerview == stagepicker)
return [stagepickerarray objectAtInde:row];
}
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component {
if (thePickerView == picker){ return [pickerViewArray count]; }
else if (thePickerView == stagepicker){ [stagepickerarray count]; }
}
the above method isn't working for me !. Am I doing this right ?

- (NSString *)pickerView:(UIPickerView *)thePickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if (pickerview == picker) {
Doesn't it sound like pickerview should be written thePickerView instead?
return [stagepickerarray objectAtInde:row];
Doesn't it sound like objectAtInde should be objectAtIndex?
else if (thePickerView == stagepicker){ [stagepickerarray count]; }
Doesn't it sound like a return is missing somewhere?

Why not use one UIPickerView with multiple components? Something along the lines of:
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
NSInteger numberOfRows;
if (component == 0) {
numberOfRows = [anArray count];
}
else if(component == 1) {
numberOfRows = [anotherArray count];
}
else {
numberOfRows = [aThirdArray count];
}
return numberOfRows;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSString *stringIndex = [NSString stringWithFormat:#"TEST"];
if(component == 0) {
return stringIndex = [anArray objectAtIndex:row];
}
else if(component == 1) {
return stringIndex = [anotherArray objectAtIndex:row];
}
else {
return stringIndex = [aThirdArray objectAtIndex:row];
}
return stringIndex;
}

Related

My label can't get value from pickerview

My numberOfComponentsInPickerView :
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 3;
}
My numberOfRowsInComponent :
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component == 0)
return 100;
if (component == 1)
return 100;
if (component == 2)
return 100;
return 0;
}
My titleForRow like this:
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component == 0)
return [NSString stringWithFormat:#"%d", row];
if (component == 1)
return [NSString stringWithFormat:#"%d", row];
if (component == 2)
return [NSString stringWithFormat:#"%d", row];
return 0;
}
my didSelectRow like this
after edited like Paras Joshi's said :
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
int year = [picker selectedRowInComponent:0];
int month = [picker selectedRowInComponent:1];
int day = [picker selectedRowInComponent:2];
if(viewPicker.tag == 1)
labelDate1.text = [year stringByAppendingFormat:#" : %d : %d", month, day];
else
labelDate2.text = [year stringByAppendingFormat:#" : %d : %d", month, day];
}
it still gives me error " bad receiver type 'int' " and i still don't get it how to fix it. how my label get data from titleForRow?
both input for year month and day all are number only (from 0 to 99) so that i wrote -> return [NSString stringWithFormat:#"%d", row];
i dont put data for my pickerview at - (void)viewDidLoad because i want my labelDate1 or labelDate2 got data from pickerview. is there any possible my label get data from pickerview like i wrote above? or must i write my data at - (void)viewDidLoad ?
for any help, thank you for watching my question.
In your program you are appending string to an integer that is the issue.
This code makes the issue. Because year is an integer.
labelDate1.text = [year stringByAppendingFormat:#" : %d : %d", month, day];
Please check with this code.
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
int year = [picker selectedRowInComponent:0];
int month = [picker selectedRowInComponent:1];
int day = [picker selectedRowInComponent:2];
NSString *date = #"";
if(viewPicker.tag == 1)
labelDate1.text = [date stringByAppendingFormat:#" %d : %d : %d",year, month, day];
else
labelDate2.text = [date stringByAppendingFormat:#"%d : %d : %d", year, month, day];
}
Did you set the UIPickerView's delegate?I mean, did your pickerView:didSelectRow:inComponent get called?
Hello #Piyo Piyo your
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
method is totally wrong, you are assigning NSInteger to NSString. Thats why you are getting en error. You should use NSArray for putting data in picker view row and picking data from here. Here i'm going to make a small sample code.
This is your viewController.h file...
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController<UIPickerViewDelegate, UIPickerViewDataSource>
{
UIPickerView *myPickerView;
NSMutableArray *arrayYear;
NSMutableArray *arrayMonth;
NSMutableArray *arrayDay;
UILabel *lblDay;
UILabel *lblMonth;
UILabel *lblYear;
}
#end
there are three array which will contain the data for day, month and year respectively and three UILabel for showing the data. and obviously one pickerview.
Now come to on your viewController.m part.
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// UIPickerView declaration by coding
myPickerView = [[UIPickerView alloc]initWithFrame:CGRectMake(0.0, 0.0, 320.0, 216.0)];
myPickerView.delegate = self;
myPickerView.showsSelectionIndicator = YES;
[self.view addSubview:myPickerView];
// add some day number to day array
arrayDay = [[NSMutableArray alloc]init];
for(int i=1;i<6;i++)
{
NSString *string = [NSString stringWithFormat:#"%d",i];
[arrayDay addObject:string];
}
// add some month string to month array
arrayMonth = [[NSMutableArray alloc]init];
[arrayMonth addObject:#"June"];
[arrayMonth addObject:#"July"];
[arrayMonth addObject:#"August"];
[arrayMonth addObject:#"September"];
[arrayMonth addObject:#"October"];
// add some year number to year array
arrayYear = [[NSMutableArray alloc]init];
for(int i=2006;i<2011;i++)
{
NSString *string = [NSString stringWithFormat:#"%d",i];
[arrayYear addObject:string];
}
//set initially text to day label
lblDay = [[UILabel alloc]initWithFrame:CGRectMake(10.0, 250.0, 90.0, 50.0)];
[lblDay setText:[arrayDay objectAtIndex:0]];
[self.view addSubview:lblDay];
//set initially text to month label
lblMonth = [[UILabel alloc]initWithFrame:CGRectMake(110.0, 250.0, 90.0, 50.0)];
[lblMonth setText:[arrayMonth objectAtIndex:0]];
[self.view addSubview:lblMonth];
//set initially text to year label
lblYear = [[UILabel alloc]initWithFrame:CGRectMake(210.0, 250.0, 90.0, 50.0)];
[lblYear setText:[arrayYear objectAtIndex:0]];
[self.view addSubview:lblYear];
//set initially selection to each component of UIPickerView
[myPickerView selectRow:1 inComponent:0 animated:NO];
[myPickerView selectRow:1 inComponent:1 animated:NO];
[myPickerView selectRow:1 inComponent:2 animated:NO];
}
//here you are returning the number of component, which are 3 in this case
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
{
return 3;
}
//this is your didSelectRow method and here you are assigning a new text to
//label accordingly to if condition
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if(component == 0)
{
lblDay.text = [arrayDay objectAtIndex:row];
}
if(component == 1)
{
lblMonth.text = [arrayMonth objectAtIndex:row];
}
if(component == 2)
{
lblYear.text = [arrayYear objectAtIndex:row];
}
}
//this is your numberOf row in component in this case each component have 5
//rows thats why i wrote only return 5; here you can put if condition here for
//returning different rows for each component
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
{
return 5;
}
// and this is showing title on rows
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
{
if (component == 0)
return [arrayDay objectAtIndex:row];
else if (component == 1)
return [arrayMonth objectAtIndex:row];
else if (component == 2)
return [arrayYear objectAtIndex:row];
else
return 0;
}
I hope this tutorial will help you. Thank you!

use two UIPickerView in the same class

I wrote this code for the first UIPickerView
- (void)viewDidLoad
NSURL *url = [NSURL URLWithString:
#"http://localhost:8080/Data/resources/converter.country/"];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
[request setDelegate:self];
[request startAsynchronous];
// countrys = [[UIPickerView alloc] init];
countrys.delegate = self;
countrys.dataSource = self;
countrys.showsSelectionIndicator = YES;
countryField.inputView=countrys;
- (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSString *codeCity;
codeCity=[countriesArray objectAtIndex:row];
return codeCity;
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [countriesCodeArray count];
}
And then i wanted to make another UIPickerView with cities . I wrote this
citys.delegate = self;
citys.dataSource = self;
citys.showsSelectionIndicator = YES;
cityField.inputView=citys;
But when i click on it i have countries list . How should i change the datasource ? And how to use the default function of the UIPickerView, like numberOfComponentsInPickerView , numberOfRowsInComponent: ... with the second UIPickerView ?
You can assign tag to your pickerviews and then can check these tags in datasource/delegate methods
citysPickerview.tag = 2
otherPickerview.tag = 1
// then you can check for these tags in pickerview datasource/delegate methods like this -
- (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSString *title;
if (pickerview.tag == 1) // this is otherPickerview
{
title=[countriesArray objectAtIndex:row]; // your logic to get title for otherpickerview
}
else if (pickerview.tag == 2) // this is citysPickerview
{
title=[countriesArray objectAtIndex:row]; // your logic to get title for cityspickerview
}
return title;
}
You should follow this same mechanism in your all datasource/delegate code :)
What you could do is set tag for the 2 UIPickerView, like so - [countryPicker setTag:1], use these tags to distinguish between the 2 picker views.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component
{
if([pickerView tag] == 1)
return [countryNames count];
else
return [cityNames count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row
forComponent:(NSInteger)component
{
if([pickerView tag] == 1)
return [countryNames objectAtIndex:row];
else
return [cityNames count];
}
For a simpler solution, just compare the pickerView pointer. That way you save the additional complexity and maintenance of using tags.
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
NSInteger numberOfRows = 0;
if (pickerView == countrys) {
numberOfRows = [countriesCodeArray count];
}
else if (pickerView == citys) {
numberOfRows = [citysCodeArray count];
}
return numberOfRows;
}
Note: This answer is based on giuseppe's comment.

Can't save UIPickerView value in NSUserDefaults

Have UIPickerView with two rows. Trying to save value of each row in NSUserDefaults. Didn't used before NSUserDefaults. Here is my code:
-(void)viewWillAppear: (BOOL) animated {
NSUserDefaults *defaultsPicker = [NSUserDefaults standardUserDefaults];
picker = [defaultsPicker objectForKey:#"picker"] ;
}
- (void)viewDidLoad {
NSArray *ar1 = [NSArray array];
for (int i = 150; i <= 210; i++)
ar1 = [ar1 arrayByAddingObject:[NSString stringWithFormat:#"%d",i]];
[ar1 retain];
self.array1 = ar1;
NSArray *ar2 = [NSArray array];
for (int j = 40; j <= 130; j++)
ar2 = [ar2 arrayByAddingObject:[NSString stringWithFormat:#"%d",j]];
[ar2 retain];
self.array2 = ar2;
[super viewDidLoad];
}
And NSUserDefaults is in IBAction
-(IBAction)calculate {
NSUserDefaults *defaultsPicker = [NSUserDefaults standardUserDefaults];
[defaultsPicker setObject:[NSNumber numberWithInt:[picker selectedRowInComponent:0 ]] forKey:#"picker"];
[defaultsPicker synchronize];
//bla bla
}
When I press the button, app crashes and log is:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFNumber selectedRowInComponent:]: unrecognized selector sent to instance 0x690df40'
UPDATE
#pragma mark -
#pragma mark Picker Data Source Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component {
if (component == secondArrayComponent) {
return [self.array2 count];
}else {
return [self.array1 count];
}
}
#pragma mark Picker Delegate Methods
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if (component == secondArrayComponent) {
return [self.array2 objectAtIndex:row];
}else {
return [self.array1 objectAtIndex:row];
}
}
In your - (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
delegate method add the following code and it should save to NSUserDefaults
UPDATE
#pragma mark -
#pragma mark Picker Data Source Methods
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView
numberOfRowsInComponent:(NSInteger)component {
if (component == secondArrayComponent) {
return [self.array2 count];
}else {
return [self.array1 count];
}
}
#pragma mark Picker Delegate Methods
- (NSString *)pickerView:(UIPickerView *)pickerView
titleForRow:(NSInteger)row forComponent:(NSInteger)component {
if (component == secondArrayComponent) {
return [self.array2 objectAtIndex:row];
}else {
return [self.array1 objectAtIndex:row];
}
}
- (void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSInteger selectedRow = [thePickerView selectedRowInComponent:0];
[[NSUserDefaults standardUserDefaults] setInteger:selectedRow forKey:#"picker"];
}
That should do as long as you make sure you have set your UIPickerView's delegate as "self" in interface builder or in your code. Also in your .h file make sure you have <UIPickerViewDelegate>
UPDATE 2
To check whether your NSUserDefaults have saved use this piece of code in an -(IBAction) of your choosing
NSInteger pickerRow = [[NSUserDefaults standardUserDefaults] integerForKey:#"picker"];
NSLog(#"%i", pickerRow);

UIPickerView for available countries

I need help regarding UIPickerView, in my application i have to display UIPickerView with available countries . If any body has already implemented country picker please share the code.
Thanks
Here's a countries plist that I created for this purpose:
https://gist.github.com/vilcsak/c205dfd153a3e465f47e
Implementation should be pretty straightforward, but here's a bit of our code:
- (id)init {
if ((self = [super init])) {
self.countries = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Countries" ofType:#"plist"]];
}
return self;
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
self.currentCountry = [[self.countries objectAtIndex:row] objectForKey:#"code"];
self.countryLabel.text = [[self.countries objectAtIndex:row] objectForKey:#"name"];
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return self.countries.count;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [[self.countries objectAtIndex:row] objectForKey:#"name"];
}
You can get a list of available country names like this:
self.countryArray = [NSMutableArray new];
for (NSString *countryCode in [NSLocale ISOCountryCodes]) {
NSString *country = [[NSLocale systemLocale] displayNameForKey:NSLocaleCountryCode value:countryCode];
[self.countryArray addObject: country];
}
and here are some UIPicker delegate methods:
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
self.countryLabel.text = [self.countryArray objectAtIndex:row];
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return self.countryArray.count;
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [self.countryArray objectAtIndex:row];
}
You can take the countries.plist from the following like and use that for ur picker input
http://code.google.com/p/reviewscraper/source/browse/trunk/Countries.plist?spec=svn22&r=22
Make an array of available country and use this array in these delgate methods and data source methods
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
--> return value at index of array
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
number of elements in array
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
return 1;
here is the link to the blog post regarding country list data picker in a popover.
http://iosblogl.blogspot.in/2015/11/pickerview-popover-with-country-list.html

UIPicker - Initial value problem

I have a UIPicker with 3 components containing numeric values, this allows the user to set the time in hh:mm:ss format. If I select the hour from the first component my UITextField looks like this: 10:(null):(null). The (null) can be removed when the user selects the appropriate mm and ss. But if the user just wants to enter 10 hours, I want the other values to be 00 instead of (null), without the user having to physically move the picker components.
Anyone have any ideas on this ?
Some code below, this question is related to the timePicker.
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if([pickerView isEqual: routePicker])
{
route.text = [[routeArray objectAtIndex:0] valueForKey:#"route_name"];
return [[routeArray objectAtIndex:row] valueForKey:#"route_name"];
}
else if([pickerView isEqual: activityPicker])
{
activity.text = [activityArray objectAtIndex:0];
return [activityArray objectAtIndex:row];
}
else if([pickerView isEqual: intensityPicker])
{
if ([intensityArray objectAtIndex:row]==#"Low")
numberIntensity=2;
else if ([intensityArray objectAtIndex:row]==#"Low-Medium")
numberIntensity=3.5;
else if ([intensityArray objectAtIndex:row]==#"Medium")
numberIntensity=5;
else if ([intensityArray objectAtIndex:row]==#"Medium-High")
numberIntensity=6.5;
else if ([intensityArray objectAtIndex:row]==#"High")
numberIntensity=8;
else numberIntensity=0;
intensity.text = [intensityArray objectAtIndex:0];
return [intensityArray objectAtIndex:row];
}
else if([pickerView isEqual: timePicker])
{
switch (component)
{
case 0:
return [hourArray objectAtIndex:row];
break;
case 1:
return [minuteArray objectAtIndex:row];
break;
case 2:
return [secondArray objectAtIndex:row];
break;
default:
return 0;
break;
}
}
else if([pickerView isEqual: distancePicker])
{
switch (component)
{
case 0:
return [distance1Array objectAtIndex:row];
break;
case 1:
return [distance2Array objectAtIndex:row];
break;
default:
return 0;
break;
}
}
else
{
return 0;
}
}
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if([pickerView isEqual: routePicker])
{
route.text = [[routeArray objectAtIndex:row] valueForKey:#"route_name"];
}
else if([pickerView isEqual: timePicker])
{
if (component == 0)
{
selectedHour = [hourArray objectAtIndex:row];
}
else if (component == 1)
{
selectedMinute = [minuteArray objectAtIndex:row];
}
else if (component == 2)
{
selectedSecond = [secondArray objectAtIndex:row];
}
time.text = [NSString stringWithFormat:#"%#:%#:%#", selectedHour, selectedMinute, selectedSecond];
}
else if([pickerView isEqual: distancePicker])
{
if (component == 0)
{
selectedDistance1 = [distance1Array objectAtIndex:row];
}
else if (component == 1)
{
selectedDistance2 = [minuteArray objectAtIndex:row];
}
distance.text = [NSString stringWithFormat:#"%#.%#", selectedDistance1, selectedDistance2];
}
else if([pickerView isEqual: activityPicker])
{
activity.text = [activityArray objectAtIndex:row];
}
else if([pickerView isEqual: intensityPicker])
{
intensity.text = [intensityArray objectAtIndex:row];
}
}
I think this line:
time.text = [NSString stringWithFormat:#"%#:%#:%#", selectedHour, selectedMinute, selectedSecond];
could be changed to:
time.text = [NSString stringWithFormat:#"%#:%#:%#",
(selectedHour ? selectedHour : #"00"),
(selectedMinute ? selectedMinute : #"00"),
(selectedSecond ? selectedSecond : #"00")];
This assumes that selectedHour, selectedMinute and selectedSecond are all initially nil outside of this code. I am away from my mac, so I haven't tested this.
Alternatively, you could initialize selectedHour, selectedMinute and selectedSecond to #"00".