Does any one know how to make dependent UIPickerView. For example when i select row 2 of component one the titles for component two change?
I have looked on the internet there is no real answer, i have tried using if and switch statements but they just crash.
It depends on how you are going to keep data. For an example if you have an array as the value of a key of a dictionary, and that dictionary have different such keys, the first column will be the keys, and on selecting one you will be displaying the array in the other column (component). - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
method should return 2.
In
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
method, you need to give the number of keys in dictionary for component 1, and count of the array of the currently selected key.
eg
if(component==0) return [[DICTIONARY allKeys] count];
else return [[DICTIONARY objectForKey:@"SELECTED_KEY"] count];
Then,
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component {
selectedIndex = [pickerView selectedRowInComponent:0];
if (component == 1 && !(selectedIndex < 0)) {
[pickerView reloadComponent:2];
[pickerView selectRow:0 inComponent:2 animated:YES];
}
}
and
- (UIView *)pickerView:(UIPickerView *)pickerView viewForRow:(NSInteger)row forComponent:(NSInteger)component reusingView:(UIView *)view {
UILabel *pickerRow = (view != nil) ? view : [[[UILabel alloc] initWithFrame:CGRectMake(5, 0, 115, 60)] autorelease];
pickerRow.font = [UIFont boldSystemFontOfSize:14];
pickerRow.textAlignment = UITextAlignmentLeft;
pickerRow.backgroundColor = [UIColor clearColor];
pickerRow.textColor = [UIColor blackColor];
pickerRow.numberOfLines = 0;
if (component == 0) {
pickerRow.text = @"DICTIONARY_ROW'th_KEY";
}
else {
pickerRow.text = [[dictionary objectForKey:@"SELECTED_KEY"] objectAtIndex:row];
}
return pickerRow;
}
I'm sure this can be accomplished using a combination of the delegate method pickerView:didSelectRow:inComponent: and reloadComponents.
Hope this helps, I had a similar situation, my requirement was when i select a country name in a component, the cities of the country should be loaded in the second component. So what i did was, i had 2 pickerview side by side and when the user selects a row in country picker i re-initiated the second picker with appropriate data.
- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { if (pickerView == countryPickerView) { if(PickerViewCity) { [PickerViewCity removeFromSuperview]; [PickerViewCity release]; PickerViewCity=nil; } PickerViewCity = [[UIPickerView alloc] initWithFrame:CGRectMake(160, 38, 320, 240)]; PickerViewArrayCity=[[countryPickerViewArray objectAtIndex:[pickerView selectedRowInComponent:0]]objectForKey:@"nodeChildArray"]; //NSLog(@"%@",PickerViewArrayCity); PickerViewCity.showsSelectionIndicator = YES; // note this is default to NO PickerViewCity.delegate = self; PickerViewCity.dataSource = self; CGAffineTransform s20 = CGAffineTransformMakeScale(0.5, 0.58); CGAffineTransform t21 = CGAffineTransformMakeTranslation(-80,-50); PickerViewCity.transform = CGAffineTransformConcat(s20, t21); PickerViewCity.layer.masksToBounds = YES; [someview addSubview:PickerViewCity]; } if (pickerView == PickerViewCity) { } }
you need to set conditions for each row of the first component (with index 0) and open a switch to select each index, I did it and worked for me:
on ...titleForRow:(NSinteger)row forComponent(NSInteger)component
{
if (component == 0) // this is first component from left to right
return [arrayForFirstComponent objectAtIndex:row];
if (component == 1) // this is second component from left to right
switch([pickerIBOutletAsYouNamedIt selectedRowInComponent:0]) // here you set content of component two depending on which row is selected from component 1
{
case 0: // remember index starts at 0
return [arrayForComponent2ForRow1inComponent1 objectAtIndex:row];
break;
//... and so on for each row in the component 1 (with index 0)
}
}
remember: YOU HAVE TO DO THIS ALSO WITH
- ...numberOfRowsInComponent:(NSInteger)component
and with
- ...didSelectRow:(NSInteger)row inComponent:(NSInteger)component
and in his last one, in selection of row at component 0 call [pikcerIBOutlet reloadComponent:1]
I think, you like to change the corresponding item of one component when change the other. It's maybe a better solution.
Code:
- (void)pickerView:(UIPickerView *)pickerView
didSelectRow:(NSInteger)row
inComponent:(NSInteger)component {
if (component == 0) {
//Here First Part of the Pickerview is represented using 0.
// dependentPicker is the Pickerview outlet
[dependentPicker selectRow:row inComponent:1 animated:YES];
[dependentPicker reloadComponent:1];
}
else
{
[dependentPicker selectRow:row inComponent:0 animated:YES];
[dependentPicker reloadComponent:1];
}
}
Note: When you use this code the component values must be Hold by two NSArray and the order of the corresponding dependent values must be same in both arrays.
来源:https://stackoverflow.com/questions/5311552/dependent-uipickerview