iOS 8自行调整高度的单元格
我使用自定义的UITableViewCells创build了一个tableview
tableview.rowHeight = UITableViewAutomaticDimension;
用于testing一个创build的单个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]; }
当我select一排我喜欢改变所选单元格的高度。 我是这样做的:
- (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
自己创build一个高度constaint(因为contentView.translatesAutoresizingMaskIntoConstraints = YES;
默认情况下)。
因此,当updateConstraints第一次运行时,系统将在contentView
上创build一个等于10.0f
的高度约束
之后当setSelected...
被调用时,我改变了我的testView
的高度,使得testView.height
(100.0f)和contentView.height
(10.0f)之间发生冲突,并且由于testView
被附加到contentView
的底部(为了自我 – 大小的细胞工作)它给出了错误。
我试过设置contentView.translatesAutoresizingMaskIntoConstraints = NO;
但是看起来UITableViewCell无法真正为单元格找出合适的大小。 (有时太宽/太小)等
实施可以dynamic改变高度的自我调整细胞的正确方法是什么?
这里有两个问题:
1. AutoLayout消息: Unable to simultaneously satisfy constraints.
这是由于您更新自定义视图的height
限制,但不更新contentView
的height
限制。 因为您还将自定义视图的bottom
约束设置为contentView bottom
,所以系统不能同时满足以下两个约束:自定义视图不能具有100的高度,并且同时连接到contentView的底部,而contentView仍然具有10的高度。
这个修复很容易。 您为contentView定义高度约束,并将其设置为您的自定义视图的高度:
[self.contentView mas_makeConstraints:^(MASConstraintMaker *make) { make.height.equalTo(self.testView); }];
这解决了这个问题。
2.更新单元格的高度
更新单元格高度并不是那么容易,因为单元格高度是由UITableViewController
处理的,而不是单元格本身。 当然,你可以改变你的单元格的高度,但只要UITableViewController
不给单元格足够的空间,就不会看到新的单元格高度。 你会看到你现在更高的单元将重叠下一个单元。
所以你需要一个方法来告诉UITableViewController
它应该更新你的单元格的高度。 你可以通过调用reloadRowsAtIndexPaths:withRowAnimation:
这重新加载细胞,也很好地animation。 所以单元格不得不在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 }
然后,当单元格更改高度时,只需执行闭包,单元格就会重新加载:
func theFunctionWhereTheHeightChanges() { // change the height heightDidChange?() }