2015-05-26 25 views
3

我创建使用iOS 8的自上浆细胞与改变高度

tableview.rowHeight = UITableViewAutomaticDimension;

具有自上浆UITableViewCells一个的tableview用于测试的创建单个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]; 
} 

当我选择一行我喜欢改变所选单元格的高度。

- (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创造本身就是一个高度constaint(因为contentView.translatesAutoresizingMaskIntoConstraints = YES;我通过这样做每个默认值)。

所以当updateConstraints是第一次运行时,系统将在contentView等于10.0f

后来当setSelected...叫我改变我的testView的高度,创造一个高度约束所以那里有testView.height(100.0f)之间的冲突contentView.height(10.0f)并且由于testView附加到contentView的底部(为了使自定尺寸的单元工作),它给出了错误。

我试过设置contentView.translatesAutoresizingMaskIntoConstraints = NO;,但它似乎UITableViewCell无法真正找出一个适当的单元格大小。 (有时它太宽/太小)等。

什么是适当的方式来实现自动调整大小的细胞,它们的高度可以动态变化?

+0

你有没有设置'estimatedRowHeight'财产? – Michael

+0

我没有设置estimatedRowHeight :)但只是测试,并没有对高度限制冲突的问题有任何影响。 –

回答

0

这里有两个问题:

1.自动版式消息:Unable to simultaneously satisfy constraints.

这是由您更新您的自定义视图的height约束造成的事实,但你不更新contentView“约束条件。由于您还将自定义视图的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:来完成。重新加载单元格并且也很好地动画。因此,细胞在某种程度上具有呼吁UITableViewController该方法。那里的挑战:A 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?() 
} 
+0

对我不起作用(reloadRowsAtIndexPaths会发生崩溃),并且将testView链接到contentView的约束也会触发Autolayout冲突。 – Mikael