ios – 具有相对约束的自动布局,不影响systemLayoutSizeFittingSize:用于UITableViewCell

我有一个动态高度UITableViewCells的UITableView,我正在使用自动布局来计算关于主题this excellent answer的高度.到现在为止还挺好.

我正在调整应用程序以使用更大的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,即UITableViewCell contentView.

但是,当我在单元格的contentView上调用systemLayoutSizefittingSize:时,它似乎完全忽略了相对高度约束,并且得到的单元格高度太小而不适合图像.

如果我设置显式高度约束而不是相对高度约束,则没有问题.类似地,如果我将UIImageView子类化并在intrinsicContentSize中返回显式大小,则没有问题.

我甚至在我的UIImageView子类中尝试了以下内容

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

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

其中intrinsicSizeforAutolayout是我为此目的定义的属性.我认为这可能与为UILabels设置preferredMaxLayoutWidth解决类似问题的方式类似.

但不是.它不起作用.

看起来我几乎没有办法使用丑陋的屏幕宽度检查代码来根据屏幕宽度有条件地设置一个固定的高度约束,这是我真正想要避免的,因为它首先打破了使用自动布局的目的.

解决方法

单元格的contentView的宽度认情况下没有任何约束(其宽度仅在SDK添加到表视图时由SDK设置),因此当您调用systemLayoutSizefittingSize:时,约束求解器假定它有效压缩尝试找到有效解决方案时所需的宽度,当然会导致错误的高度.

解决此问题,您可以向contentView添加一个约束,将其宽度修复为最终的单元格/表格视图宽度.这是有效的,因为该约束将被纳入单元格大小布局传递中,并导致systemLayoutSizefittingSize:按预期工作.

使用PureLayout,我建议做类似的事情:

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

请注意,为约束设置小于required的优先级并不是一个坏主意,因为这只是为了帮助调整大小操作,并且如果它被破坏,您不希望出现异常(可能是未来的SDK更改)表视图单元格如何工作).但这可能并不重要.

此外,像往常一样,您可能希望确保此约束仅添加一次(并非每次调用tableView:heightForRowAtIndexPath:) – 这应该很容易.

请参阅此处以获取示例项目的fork的特定解决方案:https://gist.github.com/smileyborg/0a2082a4d26fcc7fde4d

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...