iOS 8中未见UITableViewCell约束。如何缓解此问题?

时间:2015-02-01 01:56:29

标签: ios uitableview swift

我试图理解为什么我在单元格中为我的单元格中的不同标签设置的约束没有完成。这很重要,因为我的身高是动态的。

过去两天我遇到了这个问题,这让我感到困扰。不,UITableViewAutomaticDimension不是我想要的。

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

    var cell = self.feed.dequeueReusableCellWithIdentifier("post") as PostCell

    var post = self.posts[indexPath.row]

    cell.name.text = post.name
    cell.timestamp.text = post.timestamp
    cell.postBody.text = post.body

    println("\(cell.name.constraints())")
    println("\(cell.postBody.constraints())")

    cell.contentView.setTranslatesAutoresizingMaskIntoConstraints(false)
    cell.setNeedsUpdateConstraints()     
    cell.updateConstraintsIfNeeded()

    cell.bounds = CGRectMake(0.0, 0.0, CGRectGetWidth(feed.bounds), CGRectGetHeight(cell.bounds))

    cell.setNeedsLayout()
    cell.layoutIfNeeded()

    var height = cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingExpandedSize).height

    height += 1.0

    return height
}

当我打印为cell.postBody设置的约束时,我得到[]。但是,我有5个约束。 Superview的尾随空间,Superview的空间,Superview Equals 4的底部空间,2个不同标签的2个顶部空间等于8。

如果我的代码无法通过Storyboard查看约束,我该如何以编程方式设置这5个约束

我正在更新的方式:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    var cell = self.feed.dequeueReusableCellWithIdentifier("post") as PostCell

    var post = self.posts[indexPath.row]

    cell.name.text = post.name
    cell.timestamp.text = post.timestamp
    cell.postBody.text = post.body

    if cachedHeights[post.id] == nil && cell.bounds.height != 0.0 {
        cachedHeights[post.id] = cell.bounds.height
    }

    return cell
}

func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

    var post = posts[indexPath.row]

    if cachedHeights[post.id] != nil {
        return cachedHeights[post.id]!
    } else {
        return 70
    }
}

问题是,我不确定cell.bounds.height是否完全准确。我的意思是,我认为它有时使用前一个大单元格的高度(也许是从新单元出列的单元格。)

1 个答案:

答案 0 :(得分:1)

标签上没有约束条件。这就是他们的constraints属性返回空数组的原因。

您会在标签上找到约束条件。 superview,cell.contentsView

您可以跳过对setNeedsUpdateConstraintsupdateConstraintsIfNeeded的来电,因为layoutSubviews会调用updateConstraintsIfNeeded

在切换到自行调整大小单元之前使用的旧方法:

我没有任何快速的代码,但是在切换到自行调整大小的单元之前,这里有来自应用程序的一些旧代码。它(隐式地)使用故事板单元格中标签上的约束。我唯一不同的就是缓存尺寸单元。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static LeftDetailTableViewCell *cell;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    });

    // configure the cell for this indexPath

    [self configureCell:cell atIndexPath:indexPath];

    // Set the sizing cell's width to the tableview's width

    cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(tableView.bounds), CGRectGetHeight(cell.bounds));

    [cell setNeedsLayout];
    [cell layoutIfNeeded];

    // get the fitting size

    CGSize s = [cell.contentView systemLayoutSizeFittingSize: UILayoutFittingCompressedSize];
    return s.height + 1.0;
}

<强>更新

这是我现在使用的代码,适用于iOS 8中的自定义单元格。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    BIBLETableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

    [cell adjustSizeToMatchWidth:CGRectGetWidth(self.tableView.frame)];

    [self configureAccessoryTypeForCell:cell forRowAtIndexPath:indexPath];

    [cell adjustConstraintsToMatchSeparatorInset:self.tableView.separatorInset];

    [self configureCell:cell forRowAtIndexPath:indexPath];

    [cell setNeedsUpdateConstraints];
    [cell updateConstraintsIfNeeded];

    return cell;
}

我的子类细胞有:

- (void)adjustSizeToMatchWidth:(CGFloat)width
{
    // Workaround for visible cells not laid out properly since their layout was
    // based on a different (initial) width from the tableView.

    CGRect rect = self.frame;
    rect.size.width = width;
    self.frame = rect;

    // Workaround for initial cell height less than auto layout required height.

    rect = self.contentView.bounds;
    rect.size.height = 99999.0;
    rect.size.width = 99999.0;
    self.contentView.bounds = rect;
}

- (void)adjustConstraintsToMatchSeparatorInset:(UIEdgeInsets)inset
{
    if (self.leadingMargins)
    {
        for (NSLayoutConstraint *constraint in self.leadingMargins)
        {
            constraint.constant = inset.left;
        }
    }

    if (self.trailingMargins)
    {
        for (NSLayoutConstraint *constraint in self.trailingMargins)
        {
            constraint.constant = self.accessoryType == UITableViewCellAccessoryDisclosureIndicator ? 0.0f : inset.left;
        }
    }
}