UIPickerView selectRow无法按预期工作

时间:2014-09-14 11:11:43

标签: objective-c uipickerview ios8 uipickerviewdatasource

我创建了一个UIPickerView,它有两个组件,第一个组件(A)的固定行数设置为13.另一个组件(B)具有可变数量的行,这取决于在(A)中选择的行。

加载UIPickerView时,我调用以下内容,以便我可以在两个组件中默认选择,但是我遇到的问题是只有组件(A)显示正确的值。组件(B)没有显示正确的行集或正确的选择。

[picker selectRow:rowA inComponent:COMPONENT_A animated:YES];
[picker reloadAllComponents];
[picker selectRow:rowB inComponent:COMPONENT_B animated:YES];

我在调用此代码后尝试打印出以下内容,似乎打印出正确的值,但当选择器显示时,只有组件(A)显示正确的值和选择。

NSLog(@"(A) - row selected: %i", [picker selectedRowInComponent:COMPONENT_A]);
NSLog(@"(A) - number of rows: %i", [picker numberOfRowsInComponent:COMPONENT_A]);

NSLog(@"(B) - row selected: %i", [picker selectedRowInComponent:COMPONENT_B]);
NSLog(@"(B) - number of rows: %i", [picker numberOfRowsInComponent:COMPONENT_B]);

有没有人对如何调试此问题或问题可能有任何想法?

更新

- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
{
    return 2;
}

- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
{
    switch (component) {
        case COMPONENT_A:
        {
            return 13;
        }
        case COMPONENT_B:
        {
            NSInteger selectedRowIdx = [picker selectedRowInComponent:COMPONENT_A];

            switch (selectedRowIdx) {
                case A:   return 2;
                case B:   return 4;
                case C:   return 6;
                case D:   return 8;
                case E:   return 10;
                case F:   return 12;
                case G:   return 14;
                case H:   return 16;
                case I:   return 18;
                case J:   return 20;
                case K:   return 22;
                case L:   return 24;
                default:    return 1;
            }
        }
    }

    return -1;
}


#pragma mark UIPickerViewDelegate

- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
{
    switch (component) {
        case COMPONENT_A:
        {
            switch (row) {
                case A:   return @"A";
                case B:   return @"B";
                case C:   return @"C";
                case D:   return @"D";
                case E:   return @"E";
                case F:   return @"F";
                case G:   return @"G";
                case H:   return @"H";
                case I:   return @"I";
                case J:   return @"J";
                case K:   return @"K";
                case L:   return @"L";
                default:    return @"";
            }
        }
        case COMPONENT_B:
        {
            if (row == 0) {
                return @"";
            } else {
                return [NSString stringWithFormat:@"%i", (int)row];
            }
        }
    }

    return nil;
}

3 个答案:

答案 0 :(得分:4)

pickerView似乎没时间呼吸正常,所以我建议你让viewDidLoad正常加载pickerView,然后在-viewDidAppear:中执行你的工作。

嗯......无论如何你想要animated:YES,再一次,在-viewDidLoad甚至-viewWillAppear

中再没有意义

试试这个:

-(void)viewDidAppear:(BOOL)animated
{
    [picker selectRow:rowA inComponent:COMPONENT_A animated:YES];

    //no point reloading all components, just B
    [picker reloadComponent:COMPONENT_B];

    [picker selectRow:rowB inComponent:COMPONENT_B animated:YES];
}

此外,您所在的地方:

NSInteger selectedRowIdx = [self selectedRowInComponent:COMPONENT_A];

不应该是

NSInteger selectedRowIdx = [pickerView selectedRowInComponent:COMPONENT_A];

答案 1 :(得分:1)

UIPickerView的一个奇怪的怪癖是当你打电话

`[.. selectRow: inComponent: animated: ]`

这将触发对代理人的调用

[pickerView: didSelectRow: inComponent: ]

因此可以很容易地创建无意的竞争条件,因此请检查代理的 pickerView:didSelectRow:inComponent:方法,并注意这是在中间调用设置第一个组件的结果。您可能最好为component0中选择的内容存储变量,然后关闭该变量,而不是关闭选择器中选择的内容。您也可以考虑存储一个布尔值(listenToPicker),这样您就可以通过将didSelect内容放入 if(listenToPicker){.....} 中,然后在设置之前将其关闭。 selectRow:animated:调用你可以将 listenToPicker 设置为NO,在 viewDidAppear 中设置所有组件后将其恢复为YES。祝你好运

答案 2 :(得分:0)

这可能是一个迟到的答案,但我只是面对这个问题并以下列方式解决了它

  1. func pickerView(_:didSelectRow:inComponent)

  2. 中实施view controller
  3. 连续调用以下两个函数。

    2.1 pickerView.selectRow(selectedIndex, inComponent: 0, animated: true)

    2.2。 yourViewController.pickerView(pickerView, didSelectRow: selectedIndex, inComponent: 0)