【问题标题】:UIPickerView with multiple components / 3rd component items based on component 1 and 2 selection基于组件 1 和 2 选择的具有多个组件/第 3 个组件项的 UIPickerView
【发布时间】:2015-03-31 15:45:19
【问题描述】:

我刚刚创建了一个包含三个组件的 UIPickerView。用户在轮子 1 和 2 中选择数字,并根据这些选择显示轮子/组件 3 中两个可能的数组之一。我已经让它工作正常,但有一个例外:

问题: 为了根据组件 1 和 2 的选择更新第 3 个组件,用户必须通过移动选择轮实际物理选择项目。但是可能存在用户想要使用默认选择(在我的情况下是组件 1 和 2 中的 NSString“0”)并且不触摸这些轮子的情况。因此组件 3 不会得到更新。

知道如何解决这个问题吗?有没有一种方法可以在用户选择第三个组件中的项目之前更新 UIPickerView,以便在不让用户实际移动这些轮子的情况下将组件 1 和 2 中的默认选择作为实际选择进行欺骗?

或者让我们这样表述问题:我可以自动选择 UIPickerView 的默认行而不用手指选择特定行吗?

我尝试完成的附加说明: 当用户单击文本字段时,将打开一个包含三列的 UIPickerView。在第一个轮子中,用户选择一个介于 0 和 16 之间的数字,在第二个轮子中,他将选择一个分数,在第三个轮子中,他将选择一个测量单位。例如: 1 1/2 杯, 1盎司, 1/2杯, 等等 根据数字和分数选择,第三个选择轮中的单位名称将以单数或复数形式显示(1 杯对 2 杯)。只要触摸前两个轮子并完成物理选择,整个事情就可以完美运行。问题:让我们以用户想要选择“1 盎司”为例。他会将第一个轮子移动到 1,将第二个轮子单独放置(因为它已经定位在 0 上),然后选择“盎司”。但是使用我的代码,第三个轮子不会更新为单数拼写。仅当我实际移动第二个轮子并返回 0 时。然后第三个轮子立即改变。

谢谢!!

这是我目前的代码:

    _countPickerData = @[@"0", @"1", @"2", @"3", @"4", @"5", @"6", @"7", @"8", @"9", @"10", @"11", @"12", @"13", @"14", @"15", @"16"];
        _fractionPickerData = @[@"0", @"1/2", @"1/4", @"1/8", @"3/4", @"3/8", @"5/8", @"7/8"];
        _singularUnitPickerData = @[@"NONE", @"ounce", @"cup", @"pound"];
        _pluralUnitPickerData = @[@"NONE", @"ounces", @"cups", @"pounds"];

// The number of columns of data
    - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
    {
        return 3;
    }

    // The number of rows of data
    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component
    {
        switch (component) {
            case 0: return [_countPickerData count];
            case 1: return [_fractionPickerData count];
            case 2:
                 if (([countHelper isEqualToString:@"1"] && [countFractionHelper isEqualToString:@"0"]) || ([countHelper isEqualToString:@"0"] && ([countFractionHelper isEqualToString:@"1/2" ] || [countFractionHelper isEqualToString:@"1/4"] || [countFractionHelper isEqualToString:@"1/8"])))
                {
                    return [_singularUnitPickerData count];
                }
                else
                {
                    return [_pluralUnitPickerData count];
                }
        }
        return 0;
    }

    // The data to return for the row and component (column) that's being passed in
    - (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component
    {
        switch (component)
        {
            case 0: return [_countPickerData objectAtIndex:row];
            case 1: return [_fractionPickerData objectAtIndex:row];
            case 2:
                if (([countHelper isEqualToString:@"1"] && [countFractionHelper isEqualToString:@"0"]) || ([countHelper isEqualToString:@"0"] && ([countFractionHelper isEqualToString:@"1/2" ] || [countFractionHelper isEqualToString:@"1/4"] || [countFractionHelper isEqualToString:@"1/8"])))
                {
                    pickedUnitHelper = [_singularUnitPickerData objectAtIndex:row];
                    return pickedUnitHelper;
                }
                else
                {
                    pickedUnitHelper = [_pluralUnitPickerData objectAtIndex:row];
                    return pickedUnitHelper;
                }
            default:break;
        }return nil;
    }

    // Preparing pickerView selection for textFieldIngredientUnit
    NSInteger selectedRowUnit;
    - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
    {
        switch (component)
        {
            case 0:
                countHelper = [_countPickerData objectAtIndex:row];
                return;

            case 1:
                countFractionHelper = [_fractionPickerData objectAtIndex:row];
                return;

            case 2:
                if (([countHelper isEqualToString:@"1"] && [countFractionHelper isEqualToString:@"0"]) || ([countHelper isEqualToString:@"0"] && ([countFractionHelper isEqualToString:@"1/2" ] || [countFractionHelper isEqualToString:@"1/4"] || [countFractionHelper isEqualToString:@"1/8"])))
                {
                    pickedUnitHelper = [_singularUnitPickerData objectAtIndex:row];
                    return;

                }
                else
                {
                    pickedUnitHelper = [_pluralUnitPickerData objectAtIndex:row];
                    return;

                }
            default:break;
        }
    }

【问题讨论】:

  • 您可以将默认选择更改为“-”而不是“0”,这样无论他们选择什么,您都可以更新选择器。
  • 我想到了....但是从技术上讲,他们可以选择“-”,然后呢....?
  • 能否也贴出初始化_countPickerData、_fractionPickerData、_singularUnitPickerData、_pluralUnitPickerData、countHelper的代码?没有这些,很难说会发生什么。
  • @mjbn 不要让他们选择“-”,显示错误或警告说他们必须选择一些东西。另一种选择是在显示选择器时根据前两个组件设置第三个组件。
  • @mjbn,countHelper 是什么?

标签: objective-c xcode uipickerview


【解决方案1】:

是的,您可以自动选择一行选择器,而无需用手指触摸它。例如:

[self.pickerView selectRow:0 inComponent:2 animated:YES];

在视图出现在屏幕上之前调用它。大概在viewWillAppear:

更新:

马库斯和我通过聊天检查了这一点,我想出了一个解决方案。基本上,任何时候:

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component

被调用,如果是组件 0 或 1,我们需要重新加载组件 2。我们这样做(在 didSelectRow 方法中)这样说:

[pickerView reloadComponent:2];

他的代码中还有其他一些小问题无法正常工作,但就这个堆栈溢出问题而言,这就是需要解释的全部内容。

【讨论】:

  • 我认为这正是我试图完成的方向。就我而言,我需要做 [self.unitPicker selectRow:0 inComponent:0 animated:YES];和 [self.unitPicker selectRow:0 inComponent:1 animated:YES];我真的不明白我必须把代码准确地放在哪里。我在 ViewDidLoad 中尝试过,但它强制用户选择这些行。每当我尝试将轮子换成其他东西时,它都会跳回第 0 行。
  • 好吧,您的代码选择了第 0 行,这是默认设置,因此代码不会更改任何内容。尝试不同的行,看看是否有任何改变。
  • 嗯……就是这样。第 0 行是“0”作为字符串。如果我的用户选择“0”,我希望在组件 2 中加载一个不同的数组。基本上,我尝试做的是:他们用户选择一个数字(组件 0 和组件 2,完整的数字和分数)和一个测量单位轮 2. 根据他选择的数字/分数组合,测量单位轮以单数或复数形式显示单位。当用户选择组件 0 中的“1”和组件 1 中的“0”时,测量单位将以单数拼写显示。组件 0 中的“0”和组件 1 中的任何分数也是如此。
  • 好的,如果我理解正确,您需要调用 [self.pickerView reloadComponent:2] 来实现:“如果我的用户选择 '0',我想要一个不同的数组装入组件 2"。基本上,选择器的字符串保持不变,直到您重新加载它们。调用 [self.pickerView reloadComponent:2] 将使选取器根据您在 pickerView:tilteForRow:forComponent: 中的逻辑更新组件 2 中的内容
  • 谢谢布赖恩,我试了一下。但是只要组件 0 或 1 的选择轮没有移动,轮 3 中的任何内容都不会更新。我开始怀疑我尝试完成的工作是否可能。我实际上应该将 {self.pickerView reloadComponent:2] 放在代码中的哪个位置?
【解决方案2】:

我最近遇到了同样的问题(uipickerview 没有选择第一个值)。我试着做..

[_myPicker selectRow:0 in Component:0 animated:YES];

但这仍然没有选择值,它将选择器转到我在 selectRow 和 Component 中选择的任何内容,但没有将那个值发送到任何地方。所以我所做的是在我的选择器数组中创建一个额外的行。我的选择器值分别为 1、2、3 和 4。所以当我添加数组时,它看起来像这样......

_myPickerArray = [[NSArray alloc] initWithObjects:@" ", @"1", @"2", @"3", @"4", nil];

现在用户必须转动滚轮才能选择一些东西。在您的代码中,您正在检查输入是否为 1 的字符串。如果他们选择空格,则将不满足该条件。看看这是否有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多