内联 UIPicker 实现

Inline UIPicker Implementation

我正在尝试在 table-view 单元格内实现一个内联 UIPicker,类似于两个 this and this SO 问题。我相信我的实施很接近,但目前,当我 select 适当的单元格时,没有显示选择器。关于我做错了什么,任何人都可以指出正确的方向吗?谢谢!

下面是我确定每个部分中出现的行的位置:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    switch (indexPath.section) {
        case NotificationsSection:
            return [self tableView:tableView cellForAreaOneRowAtIndexPath:indexPath];
            break;
        case RedZoneSection:
            return [self tableView:tableView cellForAreaTwoRowAtIndexPath:indexPath];
            break;
        case TimeOfDaySection:
            return [self tableView:tableView cellForAreaThreeRowAtIndexPath:indexPath];
            break;
        default:
            return nil;
            break;
    }
}

下面是我检查每个部分中的行数的地方。我怀疑我的问题可能出在这里,但我不完全确定。

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    switch (section) {
        case AreaOneSection:
            return AreaOneRows;
            break;
        case AreaTwoSection:
            return TotalAreaTwoRows;
            break;
        case AreaThreeSection:
            return TotalAreaThreeRows;
            break;
        default:
            return 0;
            break;
    }
}

下面是我 return 每行的高度:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    CGFloat rowHeight = self.tableView.rowHeight;
    //    if (indexPath.section == TimeOfDaySection && indexPath.row == HourTimeZoneRow  && self.timePickerIsShowing == NO){
    return rowHeight;
}

最后,下面是我检查用户是否 select 编辑了我想在下面插入 UIPicker 单元格的索引路径。如果他们这样做了,那么我会调用一个方法来显示选择器。

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [self.tableView deselectRowAtIndexPath:indexPath animated:YES];

    if (indexPath.section == SectionThree && indexPath.row == RowOne  && self.timePickerIsShowing == NO){

        [tableView beginUpdates];
        [self showTimePicker];
        [tableView endUpdates];
    } else{
        [self hideTimePicker];
        [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
    }
}

最后,下面是我显示和隐藏 UIPicker 的地方。

- (void)showTimePicker
{
    self.timePickerIsShowing = YES;
    self.timePicker.hidden = NO;
    //build the index path to where the picker should be inserted here
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:HourTimeZoneRow + 1 inSection:TimeOfDaySection];

    static NSString *CellIdentifier = @"TimePickerCell";
    UITableViewCell *cell = (UITableViewCell*)[self.tableView  dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
    _timePicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 0, self.tableView.bounds.size.width, 160)];
    [cell.contentView addSubview:self.timePicker];

    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    [self.tableView reloadData];
    self.timePicker.alpha = 0.0f;
    [UIView animateWithDuration:0.25 animations:^{
        self.timePicker.alpha = 1.0f;
    }];
}

- (void)hideTimePicker {
    self.timePickerIsShowing = NO;
    self.timePicker.hidden = YES;
    [self.tableView reloadData];
    [UIView animateWithDuration:0.25
                     animations:^{
                         self.timePicker.alpha = 0.0f;
                     }
                     completion:^(BOOL finished){
                         self.timePicker.hidden = YES;
                     }];
}

在你的showPicker函数中,你好像什么都没做?你创建一个单元格,用它做一些事情,然后当该功能结束时它就死了。从我看到的任何地方都没有添加单元格?

您需要在 cellForRowAtIndexPath 中添加选择器,因为您知道的索引路径需要一个选择器。

我所做的工作只需要很少的编码。我在包含选择器视图的界面生成器中创建了一个原型单元格。在我的例子中,我还在选择器上方添加了一个工具栏,我可以在其中放置按钮以允许取消和完成。添加 suitable 属性以传递选择器初始显示的当前值。添加一个委托,用于通知创建者(您的 tableView)选择器值的变化。您可以等待它完成选择,或者使用它通过在每次值更改时重新加载正在编辑的单元格来实时更新单元格的编辑值。我更喜欢选择器可以选择一个值,你可以提交或取消它。

当一个单元格需要编辑时,我更新我的数据模型以插入一个编辑条目然后调用 [tableView reload]。在我的例子中,选择一个单元格开始编辑,单击 cancel/done 结束编辑。

此时 table 视图将开始请求单元格。这次其中之一将是您的新选择器单元格,它将用于编辑其下方的单元格。创建它时,将要编辑的数据的数据模型引用传递给它。

因此,您只需添加一个新的原型单元格类型并在需要时在 cellForRowAtIndexPath 中创建它即可实现所有这些。

您可以选择如何删除选择器。在我的例子中,我有 Cancel/Done 按钮,它只是从数据模型中删除条目并再次重新加载 table,导致它永远不会被创建。您还可以将模式设置为单击单元格以添加并再次单击以删除。同样,您只需更新数据模型并重新加载。查看时间选择器如何在新约会的 Calander 应用程序上工作。

您可能认为这是多次重新加载。然而,它只影响屏幕上的内容,我发现它比一直试图找出受影响的单元格更容易。它也很光滑。当它工作时,您可以随时优化代码。

在单元格中使用约束以确保它具有您想要的布局。