2014-11-21 114 views
4

我有UITableView与动态高度UITableViewCell s和我正在使用自动布局来计算高度根据主题this excellent answer。到现在为止还挺好。自动布局与相对约束不影响systemLayoutSizeFittingSize:对于UITableViewCell

我正在调整应用程序以适应较大的iPhone(6和6 Plus)屏幕尺寸,它大多非常简单。

但是,在我的一些单元格中,我想要跨越整个单元格宽度的图像,并且我希望图像的高度与图像的宽度成比例(0.55 *宽度具体)。到目前为止,我已经在自动布局约束条件下硬编码图像的宽度和高度,基于iPhone 6/6 Plus之前的标准320px纵向桌面视图宽度。

我认为这将是简单的添加一个相对高度的限制,像这样(我使用PureLayout):

[self.myImage autoMatchDimension:ALDimensionHeight 
        toDimension:ALDimensionWidth 
          ofView:self 
        withMultiplier:0.55f 
         relation:NSLayoutRelationGreaterThanOrEqual]; 

如果你不熟悉PureLayout,这相当于调用

[NSLayoutConstraint constraintWithItem: attribute: relatedBy: toItem: attribute: multiplier: constant:0.0f]

还有其他的约束,把它的边缘连接到superview,这是contentView的UITableViewCell

然而,当我打电话systemLayoutSizeFittingSize:对细胞的内容查看它似乎完全忽略了相对高度的限制,并将得到的细胞高度是远远太小,放不下的图像。

如果我设置了一个明确的高度约束而不是相对的约束,这没有问题。同样,如果我继承UIImageView并返回intrinsicContentSize中的显式大小,则没有问题。

我甚至试过在我UIImageView子类中的以下内容:

- (void) layoutSubviews { 
    [super layoutSubviews];  
    self.intrinsicSizeForAutolayout = self.frame.size;  
    [super layoutSubviews]; 
} 

- (CGSize)intrinsicContentSize { 
    return self.intrinsicSizeForAutolayout; 
} 

其中intrinsicSizeForAutolayout是我为宗旨定义的属性。我认为这可能类似于设置preferredMaxLayoutWidthUILabel s解决类似问题的方式。

但是没有。它不起作用。

这似乎我有一个替代使用丑陋的屏幕宽度检查代码有条件地设置一个固定的高度约束取决于屏幕宽度,我真的很想避免,因为它有点挫败使用自动布局的目的第一个地方。

+0

致电前'systemLayoutSizeFittingSize:'在屏幕外的单元格的内容查看,你在屏幕外的单元格的宽度设置为表视图的实际宽度在那个时候(6&6 Plus将会> 320pt)?如果这没有帮助,我建议尝试使用iOS 8自身尺寸调整单元机制,以查看是否可以解决问题。如果这也行不通,我猜测你的约束可能存在一些问题......如果你可以修改其中一个[示例项目](https://github.com/smileyborg/TableViewCellWithAutoLayoutiOS8)来演示这将是最有帮助的问题。 – smileyborg 2014-11-21 17:57:07

+0

我将离屏单元的宽度设置为表视图的实际宽度。我想保持iOS 7的兼容性,所以我还没有尝试过iOS 8自行调整大小的单元机制。我会试着让你得到一个示例项目来演示这个问题。 – mluisbrown 2014-11-22 21:06:42

+0

@smileyborg我试图在iOS 7示例项目中重现问题而没有成功。但是我发现在我的情况下,如果我使用Xcode 6视图调试,'UIImageView'具有基于其内容大小的约束,而在修改后的示例项目中则没有。我还应该补充一点,实际上我使用的是UIView-AutoLayout库(PureLayout的前身),而不是PureLayout本身,尽管我怀疑这会有所作为。 – mluisbrown 2014-11-23 01:33:46

回答

7

默认情况下,单元的宽度contentView没有任何约束条件(它的宽度由SDK在添加到表格视图时才会设置),因此当您调用systemLayoutSizeFittingSize:时,约束求解器会假定它是当试图找到有效的解决方案时,可以根据需要有效地压缩宽度,这当然会导致错误的高度。

要修复此问题,可以将一个约束添加到contentView,该约束将其宽度修复为最终的单元格/表格视图宽度。这是有效的,因为这个约束分解为单元大小布局过程,导致systemLayoutSizeFittingSize:按预期工作。

使用PureLayout,我建议做这样的事情:

[UIView autoSetPriority:UILayoutPriorityRequired - 1 forConstraints:^{ 
    [cell.contentView autoSetDimension:ALDimensionWidth toSize:CGRectGetWidth(tableView.bounds)]; 
}]; 

请注意,这不是一个坏主意,设定的低于所需的约束优先,只因为这仅仅是为了帮助尺寸设定操作,如果这种情况被破坏(可能是由于将来的SDK更改了表格视图单元格的工作方式),则不需要发生异常。但这可能没有关系。

此外,像往常一样,你可能想确保这个约束只添加一次(不是每次调用tableView:heightForRowAtIndexPath:) - 这应该很容易做到。

在这里看到一个具体的解决方案,以你的示例项目的叉:https://gist.github.com/smileyborg/0a2082a4d26fcc7fde4d