iOS 8自定型单元,高度不断变化

时间:2015-05-26 21:03:02

标签: ios objective-c uitableview uikit

我使用

创建了一个自定义UITableViewCells的tableview

tableview.rowHeight = UITableViewAutomaticDimension;

用于测试已创建的单个UIView,并使用以下约束将其添加到cell.contentView。 (使用砖石结构)

- (void)updateConstraints {
    UIView *superview = self.contentView;

    if (!_didSetupConstraints) {
        [self.testView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(superview);
            make.height.equalTo(@10.0f);
            make.left.equalTo(superview);
            make.right.equalTo(superview);
            make.bottom.equalTo(superview);
        }];

        _didSetupConstraints = YES;
    }

    [super updateConstraints];
}

当我选择一行时,我想改变所选单元格的高度。我是这样做的:

- (void)setSelected:(BOOL)selected animated:(BOOL)animated {
    [super setSelected:selected animated:animated];

    [self.testView mas_updateConstraints:^(MASConstraintMaker *make) {
        if (selected) {
            make.height.equalTo(@100);
        }
        else {
            make.height.equalTo(@10);
        }
    }];

    [UIView animateWithDuration:0.3f animations:^{
        [super layoutIfNeeded];
    }];
}

似乎有效,但xcode投诉有以下错误:

Unable to simultaneously satisfy constraints.

然后问题是contentView自己创建一个高度constaint(因为默认为contentView.translatesAutoresizingMaskIntoConstraints = YES;)。

因此,当首次运行updateConstraints时,系统将在contentView上创建一个等于10.0f的高度约束

之后调用setSelected...时我会改变testView的高度,因此testView.height(100.0f)和contentView.height(10.0f)之间发生冲突{1}}附加到testView的底部(为了使自定义单元格起作用),它给出了错误。

我尝试设置contentView,但似乎UITableViewCell无法确定单元格的正确大小。 (有时太宽/太小)等。

实施自动调整大小的正确方法是什么?它们的高度可以动态变化?

1 个答案:

答案 0 :(得分:0)

这里有两个问题:

<强> 1。 AutoLayout消息:Unable to simultaneously satisfy constraints.

这是因为您更新了自定义视图的height约束,但未更新contentView的{​​{1}}约束。因为您还将自定义视图的height约束设置为contentView bottom,所以系统无法满足两个约束:自定义视图的高度不能为100,同时连接到contentView的底部contentView的高度仍为10。

对此的修复非常简单。您为contentView定义高度约束并将其设置为自定义视图的高度:

bottom

这解决了这个问题。

<强> 2。更新单元格的高度

更新单元格高度并不容易,因为单元格高度由[self.contentView mas_makeConstraints:^(MASConstraintMaker *make) { make.height.equalTo(self.testView); }]; 而不是单元格本身处理。当然,您可以更改单元格的高度,但只要UITableViewController没有为单元格提供足够的空间,您就不会看到新的单元格高度。您将看到现在更高的单元格将与下一个单元格重叠。

所以你需要一种方法来告诉UITableViewController它应该更新你的细胞的高度。你可以致电UITableViewController来做到这一点。这会重新加载单元格,并且可以很好地激活它。因此,单元格必须在reloadRowsAtIndexPaths:withRowAnimation:上调用该方法。那里面临的挑战:UITableViewController没有引用其UITableViewCell(也不应该)。

你可以做的是子类UITableViewController并给它一个闭包属性,只要它的高度发生变化就可以执行它:

UITableViewCell

现在,当你在class DynamicHeightTableViewCell: UITableViewCell { var heightDidChange: (() -> Void)? ... 中出列一个单元格时,你设置了它的闭包:

UITableViewControllerDataSource

然后当单元格改变其高度时,您只需执行闭包,然后重新加载单元格:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell:UITableViewCell = tableView.dequeueReusableCellWithIdentifier("DynamicHeightTableViewCell", forIndexPath: indexPath)
    if let customCell = cell as? DynamicHeightTableViewCell {
        customCell.heightDidChange = { [weak cell, weak tableView] in
            if let currentIndexPath = tableView?.indexPathForCell(cell!) {
                tableView?.reloadRowsAtIndexPaths([currentIndexPath], withRowAnimation: .Automatic)
            }
        }
    }

    return cell
}
相关问题