Reputation: 45
I feel my code is logic and i found many example to refer to before doing this but i still couldn't solve this problem. there are more codes but i included only the ones that i think might be related. i did two components pickerview
on an actionsheet
. the pickerview
was supposed to show the cities in second component according to the state selected from the first component.it works good with Johor and Kedah but when it goes to kelantan and melaka state, it crashes. i have a doubt that it relates with the number of items. but i don't know how to solve it. any suggestion?
(let me know if more codes needed, will provide it) thank you in advance.
some of the codes: (i included numberOfRowsInComponent
,titleForRow
and didSelectRow
methods and the arrays)
StateList = [NSArray arrayWithObjects: @"Johor",@"Kedah",@"Kelantan",@"Wilayah Persekutuan",@"Melacca", nil];
JohorCityList = [[NSMutableArray alloc] initWithObjects: @"Kota Tinggi",@"Larkin Lama",@"Muar",@"Pasir Gudang", nil];
KedahCityList = [[NSArray alloc] initWithObjects: @"Langkawi",@"Alor Setar",@"Bakar Arang", nil];
KelantanCityList = [[NSMutableArray alloc] initWithObjects:@"Tanah Merah",@"Kota Bharu", nil];
KLCityList = [[NSArray alloc] initWithObjects: @"Batu Muda", @"Labuan",@"Putrajaya",@"Cheras", nil];
MelaccaCityList = [NSArray arrayWithObjects: @"Bandaraya Melaka", @"Bukit Rambai", nil];
(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component == 0) {
return [StateList count];
}
else if (component == 1){
if ([selectedState isEqualToString:@"Johor"]) {
return [JohorCityList count];
}
else if ([selectedState isEqualToString:@"Kedah"]){
return [KedahCityList count];
}
else if ([selectedState isEqualToString:@"Kelantan"]) {
return [KelantanCityList count];
}
else if ([selectedState isEqualToString:@"Wilayah Persekutuan"]) {
return [KLCityList count];
}
else if ([selectedState isEqualToString:@"Melacca"]){
return [MelaccaCityList count];
}
// else
// return [JohorCityList count];
}
return [JohorCityList count];}
(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component == 0) {
return [StateList objectAtIndex:row];
}
else if (component == 1){
if ([selectedState isEqualToString:@"Johor"]) {
return [JohorCityList objectAtIndex:row];
}
else if ([selectedState isEqualToString:@"Kedah"]){
return [KedahCityList objectAtIndex:row];
}
else if ([selectedState isEqualToString:@"Kelantan"]) {
return [KelantanCityList objectAtIndex:row];
}
else if ([selectedState isEqualToString:@"Wilayah Persekutuan"]) {
return [KLCityList objectAtIndex:row];
}
else if ([selectedState isEqualToString:@"Melacca"]) {
return [MelaccaCityList objectAtIndex:row];
}
}
return [JohorCityList objectAtIndex:row];}
(void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
NSLog(@"Selected Row %d", row);
if ([thePickerView selectedRowInComponent:0] == 0){ //JB
NSLog(@"case 0");
[thePickerView reloadComponent:1];
switch (component) {
case 0:
selectedState = [StateList objectAtIndex:row];
return;
case 1:
selectedJohorCity = [JohorCityList objectAtIndex:row];
return;
} // end switch
} // end
else if ([thePickerView selectedRowInComponent:0] == 1){ //Kedah
NSLog(@"case 1");
[thePickerView reloadComponent:1];
switch (component) {
case 0:
selectedState = [StateList objectAtIndex:row];
return;
case 1:
selectedKedahCity = [KedahCityList objectAtIndex:row];
return;
} // end switch
} // end
else if ([thePickerView selectedRowInComponent:0] == 2){ //Kelantan
NSLog(@"case 2");
[thePickerView reloadComponent:1];
switch (component) {
case 0:
selectedState = [StateList objectAtIndex:row];
return;
case 1:
selectedKelantanCity = [KelantanCityList objectAtIndex:row];
return;
} // end switch
} // end
output:
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 2 beyond bounds [0 .. 1]'
and SIGABRT stops at titleforRow method at:
return [KelantanCityList objectAtIndex:row];
Upvotes: 0
Views: 1676
Reputation: 17409
It is crash Because You have 2 item in KelantanCityList array and you are trying to access 3rd object of array.
UPdate
For More Dynamic you can use two array one with StateNames and second with Array of City's Array , You can show following Implementation:
ViewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
StateList = [NSMutableArray array];
StateNames= [[NSMutableArray alloc]initWithObjects:@"Johor",@"Kedah",@"Kelantan",@"Wilayah Persekutuan",@"Melacca", nil];
JohorCityList = [[NSMutableArray alloc] initWithObjects: @"Kota Tinggi",@"Larkin Lama",@"Muar",@"Pasir Gudang", nil];
KedahCityList = [[NSMutableArray alloc] initWithObjects: @"Langkawi",@"Alor Setar",@"Bakar Arang", nil];
KelantanCityList = [[NSMutableArray alloc] initWithObjects:@"Tanah Merah",@"Kota Bharu", nil];
KLCityList = [[NSMutableArray alloc] initWithObjects: @"Batu Muda", @"Labuan",@"Putrajaya",@"Cheras", nil];
MelaccaCityList = [[NSMutableArray alloc ]initWithObjects: @"Bandaraya Melaka", @"Bukit Rambai", nil];
selectedState=@"Johor";
[PickerView reloadAllComponents];
[StateList addObject:JohorCityList];
[StateList addObject:KedahCityList];
[StateList addObject:KelantanCityList];
[StateList addObject:KLCityList];
[StateList addObject:MelaccaCityList];
}
Picker DelegateMethod
-(NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
return 2;
}
-(NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
if (component == 0) {
return [StateList count];
}
{
int r= [[StateList objectAtIndex:[pickerView selectedRowInComponent:0]]count];
return r;
}
}
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
if (component == 0) {
return [StateNames objectAtIndex:row];
}
else
{
return [[StateList objectAtIndex:[pickerView selectedRowInComponent:0]]objectAtIndex:row];
}
return @"";
}
-(void)pickerView:(UIPickerView *)thePickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
if (component==0)
{
[thePickerView reloadComponent:1];
}
else
{
NSLog(@"selected State:%@ ", [StateNames objectAtIndex:[thePickerView selectedRowInComponent:0]]);
NSLog(@"selcted city:%@",[[StateList objectAtIndex:[thePickerView selectedRowInComponent:0]]objectAtIndex:row]);
}
}
Upvotes: 2
Reputation: 9337
This basically means that you are trying to get object out of bounds for KelantanCityList
. You are trying to get element at index 2 while the array has only 2 elements (last index in array is 1).
You should debug it and see what is going on, it might be a bad value for selectedState
which causes that you are trying to retrieve data from the wrong array. For sure checking whether index you will try to refer from array is not out of bound will help you to avoid a crash but it will not solve the basic problem which might be setting improperly value for selectedState
.
Upvotes: 1