Dependent UIPickerView

吃可爱长大的小学妹 提交于 2019-11-30 15:20:50

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)   
    {


    }   
}


Wytchkraft

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]

Ajas M.M

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!