Dependent UIPickerView
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.
精彩评论