pickerViews crashes - ios

Here is my code:
#synthesize pickerLetter, pickerNumber, pickerSymbol;
- (void)viewDidLoad {
[super viewDidLoad];
letters = [[NSArray alloc]initWithObjects:#"a", #"b", #"c", nil];
numbers = [[NSArray alloc]initWithObjects:#"1", #"2", #"3", nil];
symbols = [[NSArray alloc]initWithObjects:#"+", #"-", #"/", nil];
}
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 1;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (pickerView == pickerLetter) {
return letters.count;
} else if (pickerView == pickerNumber){
return numbers.count;
} else {
return symbols.count;
}
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (pickerView == pickerLetter) {
return [letters objectAtIndex:row];
} else if (pickerView == pickerNumber){
return [numbers objectAtIndex:row];
} else {
return [symbols objectAtIndex:row];
}
}
This is giving me
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
when I use the pickers in the Simulator.
The code that is causing the crash is
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
label.text = [NSString stringWithFormat:#"%# %# %#",[letters objectAtIndex:[pickerLetter selectedRowInComponent:0]],[numbers objectAtIndex:[pickerNumber selectedRowInComponent:1]],[symbols objectAtIndex:[pickerSymbol selectedRowInComponent:2]]];
}

You've narrowed down your issue to this code:
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
label.text = [NSString stringWithFormat:#"%# %# %#",[letters objectAtIndex:[pickerLetter selectedRowInComponent:0]],[numbers objectAtIndex:[pickerNumber selectedRowInComponent:1]],[symbols objectAtIndex:[pickerSymbol selectedRowInComponent:2]]];
}
But this line has several calls to objectAtIndex: so it's hard to know the exact issues. Plus this code is hard to read and impossible to debug. Start by splitting up this code as follows:
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSInteger letterIndex = [pickerLetter selectedRowInComponent:0];
NSString *letter = letters[letterIndex];
NSInteger numberIndex = [pickerNumber selectedRowInComponent:1];
NSString *number = numbers[numberIndex];
NSInteger symbolIndex = [pickerSymbol selectedRowInComponent:2];
NSString *symbol = symbols[symbolIndex];
label.text = [NSString stringWithFormat:#"%# %# %#", letter, number, symbol];
}
Doing this you will be able to narrow down the real cause of your issue.
As you can see, the problem is that you are referencing the wrong component number from the pickerNumber and pickerSymbol. All three pickers only have 1 component so you need to select component 0 from all three pickers.
The needed code is:
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
NSInteger letterIndex = [pickerLetter selectedRowInComponent:0];
NSString *letter = letters[letterIndex];
NSInteger numberIndex = [pickerNumber selectedRowInComponent:0];
NSString *number = numbers[numberIndex];
NSInteger symbolIndex = [pickerSymbol selectedRowInComponent:0];
NSString *symbol = symbols[symbolIndex];
label.text = [NSString stringWithFormat:#"%# %# %#", letter, number, symbol];
}
Avoid putting more than one or two method calls on a single line of code. It makes the code less readable and much harder to debug if there is a problem.

you are calling a wrong way to implement the method
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (pickerView == pickerLetter) {
return [letters objectAtIndex:row];
} else if (pickerView == pickerNumber){
return [numbers objectAtIndex:row];
} else {
return [symbols objectAtIndex:row];
}
}
change it to
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component == 0) {
return [letters objectAtIndex:row];
} else if (component == 1){
return [numbers objectAtIndex:row];
} else {
return [symbols objectAtIndex:row];
}
}

Related

Return first character of string in NSArray for UIPickerView didSelectRow

I have a UIPickerView which returns an NSArray with 4 strings. When the user scrolls the UIPickerView, a UITextField gets updated with the selected row. I would like to return the first character of each string in the NSArray and update the UITextField with that character.
As you can see from my code, I have tried to achieve this functionality by using self.noiseLevelArray = [noiseArray sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];, which I found on a few different stack overflow questions.
Here is the code for the picker:
// Noise picker
self.noisePicker = [[UIPickerView alloc]init];
[noisePicker setDataSource:self];
[noisePicker setDelegate:self];
self.noiseArray = [[NSArray alloc]initWithObjects:#"4: Extreme Noise (Impossible)", #"3: Very Noisy (Loud Shouting)", #"2: Noisy (Shouting)", #"1: Not Noisy (Normally)", nil];
//self.noiseLevelArray = [noiseArray sortedArrayUsingSelector:#selector(caseInsensitiveCompare:)];
// Call noisePicker method
[self noisePickerTextField];
Here is the code for my picker:
// Picker components
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component {
return [noiseArray count];
//return [noiseLevelArray count];
}
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
return [noiseArray objectAtIndex:row];
//return [noiseLevelArray objectAtIndex:row];
}
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSString *noiseString = [[NSString alloc]initWithFormat:#"%#", [noiseArray objectAtIndex:row]];
//NSString *noiseString = [noiseLevelArray objectAtIndex:0];
if ([self.empNoise1 isFirstResponder]) {
self.empNoise1.text = noiseString;
}
else if ([self.empNoise2 isFirstResponder]) {
self.empNoise2.text = noiseString;
}
...
As you can see, the UITextField gets updated with the full string of whichever row is selected in the UIPickerView. I would like it to still display the full string, but update the UITextField with the first character only (in this case 1, 2, 3, or 4). Any help is much appreciated!
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSString *noiseString = [[NSString alloc]initWithFormat:#"%#", [[noiseArray objectAtIndex:row] substringToIndex:1]];
//NSString *noiseString = [noiseLevelArray objectAtIndex:0];
if ([self.empNoise1 isFirstResponder]) {
self.empNoise1.text = noiseString;
}
else if ([self.empNoise2 isFirstResponder]) {
self.empNoise2.text = noiseString;
}
}
Try this. It uses the following method:
NSString * firstLetter = [word substringToIndex:1];
Try this.. `
self.empNoise1.text = [noiseString substringToIndex:1];`
Returns a new string containing the characters of the receiver up to, but not including, the one at a given index.
Link

How I can display string format on my Uilabel when selecting data from Uipickerview?

Hi I have one picker view. This picker view from web services came to
loading data. This picker view is 2 part. Picker view 1. part is
Project name. and Picker view 2. part is Project number. I want to
write on my label same picker view is 1. part I want to write on label
"A1 Unitesi", and i want to write on label2 "002" but my label on
write "DevamEdenProjelerObje:"0xada6fe0">why on my label write
"DevamEdenProjelerObje:"0xada6fe0"> ?` Can you help to me ? How i can
on my label write "A1 Unitesi" ?
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component == 0) {
return [RaporlarList count];
}
return [RaporlarList count];
}
#pragma mark Picker Delegate Methods
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component == 0) {
eObje = [RaporlarList objectAtIndex:row];
return eObje.ProjeAdii;
}
eObje = [RaporlarList objectAtIndex:row];
return eObje.ProjeNoo;
}
#pragma mark -
#pragma mark PickerView Delegate
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (component == 0)
{
NSString *resultString = [[NSString alloc] initWithFormat:#"Proje Adı : %#", [RaporlarList objectAtIndex:row]];
lblProjeAdi.text = [NSString stringWithFormat:#"%#", resultString];
}
else
{
NSString *resultString = [[NSString alloc] initWithFormat:#"Proje No: %#", [RaporlarList objectAtIndex:row]];
lblProjeNo.text = resultString;
}
}
I didn't know if I understood well but isn't that better?
if (component == 0)
{
NSString *resultString = [[NSString alloc] initWithFormat:#"Proje Adı : %#", [[RaporlarList objectAtIndex:row] ProjeAdii]];
lblProjeAdi.text = [NSString stringWithFormat:#"%#", resultString];
}
else
{
NSString *resultString = [[NSString alloc] initWithFormat:#"Proje No: %#", [[RaporlarList objectAtIndex:row] ProjeNoo]];
lblProjeNo.text = resultString;
}

How set UIPickerView in cascade

I'm trying to set two UIPickerViews, both are filled with NSDictionary, this work ok, but I need to the second UIPickerView implement a refresh depends of the selection of the first UIPickerView, understand me?
The first UIPickerView is filled this way:
for (NSDictionary *local in json) {
NSString *nombre = [local objectForKey:#"name"];
NSString *idLocal = [local objectForKey:#"id"];
self.dicLocales = [NSDictionary dictionaryWithObjectsAndKeys: idLocal, #"idLocal", nombre, #"nombreLocal", nil];
[listaLocales addObject:self.dicLocales];
}
And the second UIPickerView is filled this way:
for (NSDictionary *servicio in json) {
NSString *nombre = [servicio objectForKey:#"name"];
NSString *idServicio = [servicio objectForKey:#"id"];
self.dicServicios = [NSDictionary dictionaryWithObjectsAndKeys: idServicio, #"idServicio", nombre, #"nombreServicio", idLocal, #"idLocal", nil];
[listaServicios1 addObject:self.dicServicios];
}
You note variable idLocal, that corresponds to id of the first UIPickerView rows. Then, I need, if in the first UIPickerView is selected row with idLocal 1, in the second UIPickerView is reloaded or refreshing only with rows corresponds to idLocal 1.
Please hope somebody can help me, and sorry for my English :P
you have to implement <UIPickerViewDelegate> Method as below
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if ([pickerView isEqual:FirstPickerView]) {
//SecondPickerView fill code
[SecondPickerView reloadAllComponents];
}
else {
//SecondPickerView Selected row
}
}
and change your second UIPickerView fill Loop accordingly
I would recommend using (NSInteger)component 0 is the first row and so on.
if (component == 0) {
if (row == 0) {
}
else if (row == 1)
{
}
}
else if (component == 1)
{
selectedPositionIndex = row;
if (row == 0) {
}
else if (row == 1)
{
}
else if (row == 2)
{
}
else if (row == 3)
{
}
}
This code works for just about all the picker view methods that provide the component NSInteger.
-(UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
You will need to make sure you return the right item count for each component
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component == 0) {
return wordArray.count;
}
else if (component == 1)
{
return positionArray.count;
}
return 0;
}

How to display UIlabel with string format when selecting data from a UIPickerview

Hi I have one picker view. This picker view from web services came
to loading data. This picker view is 2 part. Picker view 1. part is
Project name. and Picker view 2. part is Project number. When open
screen Project no label is no data. when open screen Project name
label no data. But when i rotate my picker view came to data this like
Proje Adı: "A1 Unitesi" Proje No: "002". How i can When open screen
came to data like rotate my picker ?
When open screen Project Name and Project No Labels no data. I want
to came data when open screen
When I rotate picker view came to data like this.
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView {
return 2;
}
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component == 0) {
return [RaporlarList count];
}
return [RaporlarList count];
}
#pragma mark Picker Delegate Methods
- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component == 0) {
eObje = [RaporlarList objectAtIndex:row];
return eObje.ProjeAdii;
}
eObje = [RaporlarList objectAtIndex:row];
return eObje.ProjeNoo;
}
#pragma mark -
#pragma mark PickerView Delegate
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (component == 0)
{
NSString *resultString = [[NSString alloc] initWithFormat:#"Proje Adı : %#", [[RaporlarList objectAtIndex:row] ProjeAdii]];
lblProjeAdi.text = [NSString stringWithFormat:#"%#", resultString];
}
else
{
NSString *resultString = [[NSString alloc] initWithFormat:#"Proje No: %#", [[RaporlarList objectAtIndex:row] ProjeNoo]];
lblProjeNo.text = resultString;
}
}
You have selected wrong datasource for pickerview.
You are returning string, instead return the label
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component
{
// return your UILabel
}
The correct answer to my question is as follows:
-(void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
{
if (component == 0)
{
NSString *resultString = [[NSString alloc] initWithFormat:#"Proje Adı : %#", [[RaporlarList objectAtIndex:row] ProjeAdii]];
lblProjeAdi.text = [NSString stringWithFormat:#"%#", resultString];
}
else
{
NSString *resultString = [[NSString alloc] initWithFormat:#"Proje No: %#", [[RaporlarList objectAtIndex:row] ProjeNoo]];
lblProjeNo.text = resultString;
}
}

Insert element at NSMutableArray's end

I am loading an array from a web service and displaying them in picker and all works fine. My array contains random number of questions for every category of questions. Now what i want is that i wanna add one more entry "Your own question" at the end of array so that the last row of picker displays "Your own question". How can i do this
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
UILabel *retval = (id)view;
if (!retval) {
retval= [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, [pickerView rowSizeForComponent:component].width, [pickerView rowSizeForComponent:component].height)];
}
// retval.text = [idAndNameArray objectAtIndex:row];
if([pickerType isEqualToString:#"picker"])
{
retval.text = [idAndNameArray objectAtIndex:row];
}
else
{
retval.text = [quesArray objectAtIndex:row];
}
retval.font = [UIFont boldSystemFontOfSize:14];
retval.numberOfLines = 3;
return retval;
}
This code only displays number of rows(questions) fetched from the web service.
EDIT 1:
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)thePickerView
{
return 1;
}
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component
{
if([pickerType isEqualToString:#"picker"])
{
return [idAndNameArray count];
}
else
{
return [quesArray count];
}
}
EDIT 2:
Resolved by making another NSMutableArray with my custom object "Your own question" and then appending it with the array fetched from web service
NSMutableArray *customObj = [NSMutableArray arrayWithObject: #"test"];
[quesArray addObjectsFromArray:customObj];
In UIPickerViewDataSource's method called pickerView:numberOfRowsInComponent: return your array's count plus one value(return arr.count+1;), and in the method of UIPickerVIewDelegatethat you have implemented return your label with the text when the component is greater than arr.count-1 (if(row>(arr-1)){//return the label with 'Your own question'}). Good Luck!
EDIT:
- (NSInteger)pickerView:(UIPickerView *)thePickerView numberOfRowsInComponent:(NSInteger)component
{
if([pickerType isEqualToString:#"picker"])
{
return [idAndNameArray count];
}
else
{
return [quesArray count]+1;
}
}
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
UILabel *retval = (id)view;
if (!retval) {
retval= [[UILabel alloc] initWithFrame:CGRectMake(0.0f, 0.0f, [pickerView rowSizeForComponent:component].width, [pickerView rowSizeForComponent:component].height)];
}
// retval.text = [idAndNameArray objectAtIndex:row];
if([pickerType isEqualToString:#"picker"])
{
retval.text = [idAndNameArray objectAtIndex:row];
}
else
{
if(row>quesArray.count-1){
retval.text = #"You own question";
}
else{
retval.text = [quesArray objectAtIndex:row];
}
}
retval.font = [UIFont boldSystemFontOfSize:14];
retval.numberOfLines = 3;
return retval;
}

Resources