使用静态单元格隐藏UITableView中的单元格 - 并且没有自动布局崩溃

时间:2013-09-22 03:07:49

标签: ios xcode uitableview interface-builder

我有一个使用IB / Storyboard中的静态单元格创建的表格视图表单。但是,我需要在运行时隐藏一些单元格,具体取决于某些条件。

我找到了一些'答案;关于SO的这个问题,例如

UITableView set to static cells. Is it possible to hide some of the cells programmatically?

..他们专注于将单元格/行的高度设置为0.这很好,除了我现在从AutoLayout获得异常,因为无法满足约束。我如何解决这最后一个问题?我可以暂时禁用子视图的自动布局吗?在iOS7中有更好的方法吗?

9 个答案:

答案 0 :(得分:14)

我发现最好的方法是简单地处理numberOfRowsInSection,cellForRowAtIndexPath和heightForRowAtIndexPath以选择性地删除某些行。这是一个硬编码的'例如,对于我的场景,你可以做一些更聪明的事情来智能地删除某些单元而不是像这样硬编码,但这对我的简单场景来说是最简单的。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
    if (indexPath.section == 0 && hideStuff) {
        cell = self.cellIWantToShow;
    }
    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    CGFloat height = [super tableView:tableView heightForRowAtIndexPath:indexPath];
    if (indexPath.section == 0 && hideStuff) {
        height = [super tableView:tableView heightForRowAtIndexPath:[NSIndexPath indexPathForRow:2 inSection:0]];
    }
    return height;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSInteger count = [super tableView:tableView numberOfRowsInSection:section];

    if (section == 0 && hideStuff) {
        count -= hiddenCells.count;
    }

    return count;
}

答案 1 :(得分:8)

隐藏故事板上的单元格并将高度设置为0:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    let cell: UITableViewCell = super.tableView(tableView, cellForRowAtIndexPath:indexPath)
    return cell.hidden ? 0 : super.tableView(tableView, heightForRowAtIndexPath:indexPath)
    }
}

答案 2 :(得分:3)

如果确保没有触及单元格底边的约束,则自动布局不应该是barf(在iOS 6.0,6.1,7.0上测试)。你仍然会“锚定”到顶部边缘并且必须固定高度。 (当然,你可以反过来并锚定到底部。)

如果您的布局取决于顶部和底部边缘位置,则可以以编程方式删除约束(毕竟它们只是对象)。

答案 3 :(得分:3)

最简单的方法是更改​​节和行的高度。这个对我有用。

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    if (section == 3) {
        return 0;
    } else {
        return [super tableView:tableView heightForHeaderInSection:section];
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
    if (indexPath.section == 3) {
        cell.hidden = YES;
        return 0;
    } else {
        cell.hidden = NO;
        return [super tableView:tableView heightForRowAtIndexPath:indexPath];
    }
}

答案 4 :(得分:2)

犹太洁食的方法是使用动态单元格,将行高设置为0是一个黑客。静电电池非常方便,但功能有限。

答案 5 :(得分:1)

我设法避免了自动布局中的异常,首先在contentView中以编程方式删除单元格viewDidLoad上的约束,然后在heightForRowAtIndexPath中将该单元格的高度设置为0。

答案 6 :(得分:1)

我找到了一种允许你甚至排动画的方法,并且正在使用iOS 8.3。您只需要实现 tableView:numberOfRowsInSection:数据源方法,然后通过UITableView方法添加/删除行 insertRowsAtIndexPaths:withRowAnimation: deleteRowsAtIndexPaths:withRowAnimation:

以下是基于 UISwitch 状态隐藏确切行的示例:

- (IBAction)alowNotif:(id)sender {
    UISwitch *sw = (UISwitch*)sender;
    NSIndexPath *index = [NSIndexPath indexPathForRow:5 inSection:0];
    if ([sw isOn]) {
        [self.tableView insertRowsAtIndexPaths:@[index] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
    else {
        [self.tableView deleteRowsAtIndexPaths:@[index] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    if (![notifications isOn]) {
        return 5;
    }
    return 6;
}

正如上面提到的@algal, numberOfRowInSection:仍然是 UITableViewDataSource 方法,因此我们不知道它会工作多长时间。

答案 7 :(得分:0)

对我来说最好的方法是修改numberOfRowsInSection方法。我删除了我不想显示的数据源。对我来说是最好的解决方案,因为一切都在一个功能中。

(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if(section==0) {
    NSUInteger productCount = _products.count;
    for(loop trough your data) {
      if(your condition is true)
         productCount--;
      }
    }
    return productCount;
} else
    return self.groups.count;
}

答案 8 :(得分:0)

对于StoryBoard中的tableview也实现了这一点。我的单元格嵌入带有标题的部分,由xcode6 IB中的蓝色立方体表示。实际上,如果你实现了heightForHeaderInSection,heightForFooterInSection和titleForHeaderInSection,titleForFooterInSection,你可以在显示表时访问标题,并分别返回0.0和nil,并为numberOfRowsInSection返回0。

基本上它一切正常,除了隐藏了一个ca.您隐藏的每个单元格(部分)都会保留10像素高的垂直空间。知道那可能是什么吗?