iOS8 Beta 3中的UITableViewCell layoutSubviews无限循环问题

4
iOS8中引入了可自动调整大小的表视图单元格(WWDC Session 226 What's new in table and collection views)。在我的项目中,我正在尝试实现旧的固定行高行为。对我来说最重要的是将默认的cell.contentView框架缩进左右两侧。所以,我改变了cell.contentView.frame属性,紧接着调用了-[cell setNeedsLayout]方法,导致单元格陷入无限的layoutSubviews循环中。
重现步骤:
1.创建新的单个视图项目,并使用表视图控制器替换默认视图控制器
2.禁用表视图自动高度计算 -(void)viewDidLoad { [super viewDidLoad]; self.tableView.estimatedRowHeight = 0; self.tableView.rowHeight = 44; } 3.在故事板中的表视图中放置自定义单元格,
4.向自定义单元格添加任何子视图:enter image description here
5.子类化单元格并在layoutSubviews中更改contentView.frame
6.构建和运行。
结果: 模拟器陷入黑屏状态,无限循环布局子视图。
预期结果: 模拟器显示一个带有自定义框架的单元格contentView的表视图。
评论: 在进行一些调试时,我发现如果单元格上没有放置任何自定义子视图,则可以避免无限循环。因此,似乎只有满足以下条件后才会出现错误:
1.self.tableView.estimatedRowHeight = 0; self.tableView.rowHeight = 44; 2.cell.contentView.frame = CGRectMake(...) 3.单元格在xib或故事板中有自定义子视图 苹果在iOS8的“已知问题”列表中没有这个问题,所以我想知道这是否真的是iOS8中的一个bug,或者是否有人知道如何解决这个问题?
2个回答

2
这不是一个bug:每次更改视图的框架时,都会调用setNeedsLayout
我猜在iOS 8中更改cell.contentView.frame也会更改cell.bounds,从而触发重新布局。这种行为可能在不同的iOS版本中有所不同;无论如何,这些是标准视图,所以我们不应该以不支持的方式更改它们。
与其操作cell.contentView,不如向其中添加一个带有插入的自定义视图?或者简单地创建一个高度约束?

为什么当cell.contentView.frame改变时,setNeedsLayout会在单元格本身上调用?在iOS6和iOS7中,没有这样的setNeedsLayout调用。 - chebur
@chebur,我已经添加了一个可能的解释和可能的解决方案,主要观点是这些是苹果的观点,所以他们的内部工作方式可能会改变。 - ilya n.
1
@ilyan。AutoLayout约束绝对是正确的选择。这仍然可以在layoutSubviews中轻松完成,不会有太多麻烦。 - Dean Kelly

0
请在ViewDidLoad中使用以下代码行,无需指定行高。
-(void)viewDidLoad {
        [super viewDidLoad];
        self.tableView.estimatedRowHeight = 44.0f;
        self.tableView.rowHeight = UITableViewAutomaticDimension;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接