【问题标题】:How to remove UITableView's NSAutoresizingMaskLayoutLayoutConstraint?如何去掉 UITableView 的 NSAutoresizingMaskLayoutLayoutConstraint?
【发布时间】:2014-05-09 06:06:50
【问题描述】:

我设计了一个自定义的 UITableViewCell,在单元格的 contentView 中添加了一些子视图,我还在 contentView 和子视图之间添加了一些自动布局约束。

但是当我调试应用程序时,Xcode 告诉我存在约束冲突。在约束列表中,有一个 NSAutoresizingMaskLayoutLayoutConstraint 将单元格高度限制为 43,因此 Xcode 打破了我的子视图高度的约束并“压缩”它。

我试过了:

  1. 在界面生成器中,取消选中“autoreize subviews”复选框。没用。

  2. 在代码中,cell.contentView.translatesAutoResizingMaskIntoConstraints = NO。这会导致应用程序崩溃并出现异常:“执行 -layoutSubviews 后仍需要自动布局”。我已经尝试了这个问题中提出的所有解决方案:"Auto Layout still required after executing -layoutSubviews" with UITableViewCell subclass它们都不适合我。

所以我想我只能让单元格做它的自动调整大小的事情,并删除代码中的自动调整大小约束。在不破坏东西的情况下我应该怎么做?

编辑: 或者,从另一个角度来看,如何使 tableViewCell 高度灵活(随子视图高度和约束而变化)?在IB中,我必须设置它的高度,对吧?

【问题讨论】:

  • 一定有一些布局冲突。创建一些示例项目并与我们分享。然后很容易弄清楚。如果您想知道如何使用自动布局创建动态单元格高度,那么我创建了一些示例项目,可以在这里分享。

标签: ios objective-c uitableview autolayout


【解决方案1】:

你不需要设置cell.contentView.translatesAutoResizingMaskIntoConstraints = NO

为了在自动布局中获得 UITableViewCells 中的灵活高度,您需要手动计算 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 中的高度

是的,这很乏味,但没有其他办法。要自动计算高度,您需要在 UITableViewCell 中满足两个条件:

  1. 您必须确保您的所有子视图都有 translatesAutoResizingMaskIntoConstraints=NO
  2. 您的单元格子视图的约束必须推动 UITableViewCell 的顶部和底部边缘。

然后在您的- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 中,您需要为特定的 indexPath 重新创建该单元格并手动计算该单元格的高度。

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath 
*)indexPath
{

 //Configure cell subviews and constraints
 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
 [self configureCell:cell forIndexPath:indexPath];

 //Trigger a layout pass on the cell so that it will resolve all the constraints.
 [cell setNeedsLayout];
 [cell layoutIfNeeded];

 //Compute the correct size of the cell and get the height. This is where the magic happens.
 CGFloat height = [cartItemCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize].height;
    height += 1.0f

 return height;

}

请注意systemLayoutSizeFittingSize 与 UITextViews 不一致。在这种情况下,您必须使用另一种方式手动计算整个单元格的高度。您还可以通过缓存每个 indexPath 的高度来进行一些性能优化。

这篇博文对做什么有更详细的描述,但要点基本上就是我上面提到的。 :http://johnszumski.com/blog/auto-layout-for-table-view-cells-with-dynamic-heights

【讨论】:

  • 谢谢!我想我的问题是我使用界面生成器来布局子视图。而IB默认为单元格定义了一个固定的高度,这会转化为布局约束并导致冲突。所以你的建议是我删除 .xib 文件并编写代码来布局子视图,对吧?
  • 或者有什么办法可以去掉界面生成器中单元格的固定高度?正如您所说,用代码布置视图非常乏味,因为有很多边距限制。
  • 其实tableView:heightForRowAtIndexPath的实现不需要去掉IB。只要您在 UITableViewDelegate(很可能是您的 UITableViewController)中的代码中实现 tableView:heightForRowAtIndexPath,您仍然可以更改单元格行的高度。如果已经设置了约束,您可以通过在单元格中添加您需要的任何内容(UILabel 等)来扩展它并调用 systemLayoutSizeFittingSize 来配置单元格。
【解决方案2】:

我已经为具有自动布局的动态表格视图单元格高度创建了一些示例代码。您可以使用以下链接下载该项目。

DynamicTableViewCellHeight

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 2017-09-03
    • 1970-01-01
    • 2015-04-30
    • 2019-04-23
    • 2023-03-28
    • 2018-07-05
    • 1970-01-01
    • 2019-11-28
    • 2011-01-17
    相关资源
    最近更新 更多