iOS 8具有可变高度的自调整大小单元格
我使用创建了一个具有自调整大小的UITableViewCells的tableviewiOS 8具有可变高度的自调整大小单元格,ios,objective-c,uitableview,uikit,Ios,Objective C,Uitableview,Uikit,我使用创建了一个具有自调整大小的UITableViewCells的tableview tableview.rowHeight=UITableViewAutomaticDimension 对于测试,创建了一个UIView,并使用以下约束将其添加到cell.contentView。(使用砖石) 选择行时,我希望更改所选单元格的高度。我通过以下方式做到这一点: - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super
tableview.rowHeight=UITableViewAutomaticDimension代码>
对于测试,创建了一个UIView
,并使用以下约束将其添加到cell.contentView
。(使用砖石)
选择行时,我希望更改所选单元格的高度。我通过以下方式做到这一点:
- (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出现以下错误:
无法同时满足约束。
然后,问题是contentView
正在自己创建高度约束(因为contentView.translatesAutoResistingGMaskintoConstraints=YES;
)
因此,当第一次运行updateConstraint时,系统将在contentView
上创建一个等于10.0f
之后,当调用setSelected…
时,我会更改testView
的高度,因此testView.height
(100.0f)和contentView.height
(10.0f)之间存在冲突,因为testView
附在contentView
的底部(以便自调整单元格大小)它给出了错误的答案
我试着设置contentView.translatesAutoResizezingMaskintoConstraints=NO
但是UtableViewCell似乎无法为单元格找到合适的大小。(有时它太宽/太小)等等
实现可动态改变高度的自调整单元格大小的正确方法是什么?这里有两个问题:
1。自动布局消息:无法同时满足约束。
这是因为您更新了自定义视图的高度
约束,但未更新内容视图的高度
约束。由于您还将自定义视图的bottom
约束设置为contentViewbottom
,因此系统无法同时满足这两个约束:自定义视图的高度不能为100,同时连接到contentView的底部,而contentView的高度仍然为10
解决这个问题相当容易。可以为contentView定义高度约束,并将其设置为自定义视图的高度:
[self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(self.testView);
}];
这就解决了问题
2。更新单元格的高度
更新单元格高度并不容易,因为单元格高度是由UITableViewController
处理的,而不是单元格本身。当然,您可以更改单元格的高度,但只要UITableViewController
没有给单元格足够的空间,您就看不到新的单元格高度。您将看到现在较高的单元格将与下一个单元格重叠
因此,您需要一种方法来告诉UITableViewController
它应该更新单元格的高度。您可以通过调用reloadRowsAtIndexPaths:withRowAnimation:
来实现这一点。这将重新加载单元格,并使其具有良好的动画效果。因此,单元格必须在UITableViewController
上调用该方法。这里的挑战是:UITableViewCell
没有引用它的UITableViewController
(它应该没有)
您可以做的是子类UITableViewCell
,并为其提供一个closure属性,它可以在其高度发生变化时执行该属性:
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
}
然后,当单元改变其高度时,您只需执行闭包,单元就会重新加载:
func theFunctionWhereTheHeightChanges() {
// change the height
heightDidChange?()
}
您是否设置了estimatedRowHeight
属性?我没有设置estimatedRowHeight:),但只是进行了测试,它对高度约束冲突的问题没有任何影响。对我不起作用(重新加载RowsatindExpaths时可能会发生崩溃)将testView链接到contentView的约束也会触发自动布局冲突。
func theFunctionWhereTheHeightChanges() {
// change the height
heightDidChange?()
}