UITableView 中的内联 UiPickerView

Posted

技术标签:

【中文标题】UITableView 中的内联 UiPickerView【英文标题】:inline UiPickerView in UITableView 【发布时间】:2014-12-18 13:16:13 【问题描述】:

我使用了两个以上的内联选择器视图(不是 UIDatePickerView),它在所有转换中都能正常工作,但我的问题是它混合了数据源值并显示了两个混合值。

我刚刚使用 Apple 的示例作为内联日期选择器进行检查。

我有 data1PickerView 和它自己的两个 DataSource,分别命名为 data1data2

当我在tableViewCell didSelect上打开pickerView时我的代码如下

data1=[NSMutableArray arrayWithObjects:@"1",@"2",@"3",@"4",nil];
data2=[NSMutableArray arrayWithObjects:@"a",@"b",@"c",@"d",nil];

#pragma mark - UITableViewDelegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

    UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];


    if(indexPath.row==1)
        isData1=TRUE;
        isData2=FALSE;
    

    else if(indexPath.row==2)

        isData2=TRUE;
        isData1=FALSE;
    
    if (cell.reuseIdentifier == kDateCellID)
    
        if (EMBEDDED_DATE_PICKER)
            [self displayInlineDatePickerForRowAtIndexPath:indexPath];
        else
            [self displayExternalDatePickerForRowAtIndexPath:indexPath];
    
    else
    
        [tableView deselectRowAtIndexPath:indexPath animated:YES];
    

/*! Reveals the date picker inline for the given indexPath, called by "didSelectRowAtIndexPath".

 @param indexPath The indexPath to reveal the UIDatePicker.
 */
- (void)displayInlineDatePickerForRowAtIndexPath:(NSIndexPath *)indexPath

    // display the date picker inline with the table content
    [self.tableView beginUpdates];

    BOOL before = NO;   // indicates if the date picker is below "indexPath", help us determine which row to reveal
    if ([self hasInlineDatePicker])
    
        before = self.datePickerIndexPath.row < indexPath.row;
    

    BOOL sameCellClicked = (self.datePickerIndexPath.row - 1 == indexPath.row);

    // remove any date picker cell if it exists
    if ([self hasInlineDatePicker])
    
        [self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:self.datePickerIndexPath.row inSection:0]]
                              withRowAnimation:UITableViewRowAnimationFade];
        self.datePickerIndexPath = nil;
    

    if (!sameCellClicked)
    
        // hide the old date picker and display the new one
        NSInteger rowToReveal = (before ? indexPath.row - 1 : indexPath.row);
        NSIndexPath *indexPathToReveal = [NSIndexPath indexPathForRow:rowToReveal inSection:0];

        [self toggleDatePickerForSelectedIndexPath:indexPathToReveal];
        self.datePickerIndexPath = [NSIndexPath indexPathForRow:indexPathToReveal.row + 1 inSection:0];
    

    // always deselect the row containing the start or end date
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];

    [self.tableView endUpdates];

    // inform our date picker of the current date to match the current cell
    [self updateDatePicker];



// The number of columns of data
- (int)numberOfComponentsInPickerView:(UIPickerView *)pickerView

    return 1;


// The number of rows of data
- (int)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component


    if(isData1)
    return data1.count;
    else if(isData2)
        return data2.count;
    else
        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


    if(isData1)
        return [data1 objectAtIndex:row];
    else if(isData2)
        return [data2 objectAtIndex:row]
        ;
else
    return @"";


- (void)toggleDatePickerForSelectedIndexPath:(NSIndexPath *)indexPath

    [tblRegister beginUpdates];

    NSArray *indexPaths = @[[NSIndexPath indexPathForRow:indexPath.row + 1 inSection:0]];

    // check if 'indexPath' has an attached date picker below it
    if ([self hasPickerForIndexPath:indexPath])
    
        // found a picker below it, so remove it
        [tblRegister deleteRowsAtIndexPaths:indexPaths
                              withRowAnimation:UITableViewRowAnimationFade];
    
    else
    

        // didn't find a picker below it, so we should insert it
        [tblRegister insertRowsAtIndexPaths:indexPaths
                              withRowAnimation:UITableViewRowAnimationFade];
    

    [tblRegister endUpdates];

谁能告诉我是什么原因导致我的 data1 数据源使用 data2 数据源显示值,反之亦然,如下图所示

【问题讨论】:

你能显示你为data1pickerView设置数据源的代码吗? 你检查过UIPickerView的数据源,你用过数组还是NSSet或者字典?我问是因为在您的图像中数据的顺序不同?而且我猜,您可能在不删除先前值的情况下附加了两个 PickerView 的数据源 @Janmenjaya 我有两个不同的数据源数组,请检查更新后的答案。 我们可以看看你的方法吗:[self toggleDatePickerForSelectedIndexPath:indexPathToReveal]? @AperioOculus 请查看更新后的问题 【参考方案1】:

我怀疑isData1isData2 布尔值的值不是您在UI 呈现这些选择器视图时所期望的值。我希望如果你在 - (NSString*)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component 方法上放置一个断点,你会看到一些错误的东西。

【讨论】:

以上是关于UITableView 中的内联 UiPickerView的主要内容,如果未能解决你的问题,请参考以下文章

使用内联选择器的 UITableView 滚动性能

同一视图中的两个 uipicker

Swift UI 中的 UIPicker

用 contentsOfDirectory Swift 填充 uipicker

UIPicker 作为 UITextfield 键盘的输入

在其他视图控制器的标签上显示 UIPicker 选择