systemLayoutSizeFittingSize:UILayoutFittingCompressedSize 不压缩

systemLayoutSizeFittingSize:UILayoutFittingCompressedSize doesn't compress

我在 iOS 8.X e iOS7.x.

中遇到自动布局和 UITableView header (tableHeaderView) 的问题

self.HeaderView 是一个使用自动布局构建的 XIB。 它在滚动查看器内部使用,然后是其他视图,结果是正确的。

然后我将其设置为 table 视图的 header(如 here 所述):

self.tableView.tableHeaderView = self.HeaderView;
[self.HeaderView setNeedsLayout];
[self.HeaderView layoutIfNeeded];
CGSize headerViewSize = [self.HeaderView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
CGRect frame = self.HeaderView.frame;
frame.size.height = headerViewSize.height;
self.HeaderView.frame = frame;
self.tableView.tableHeaderView = self.HeaderView;

但结果高度比预期的要大。我不明白为什么。约束似乎没问题,否则为什么在滚动视图中结果是正确的?

如果在 IB 中我调整了容器框架的高度,约束就会更新,不会有任何歧义。

为什么 UILayoutFittingCompressedSize 不压缩视图?

#update

我发现了问题。基本上约束是正确的。

调用 layoutSubviews 后,UIImageView 的大小正确。宽度和高度符合预期。 问题在于 systemLayoutSizeFittingSize:UILayoutFittingCompressedSize 的工作方式。

它不是使用 UIImageView 大小(已正确调整大小)计算大小,而是使用 UIImage 大小(哪个源文件更大)

那么,我该怎么做才能强制 systemLayoutSizeFittingSize:UILayoutFittingCompressedSize 使用 UIImageView 大小来计算大小??

我是这样做的:我为 header 视图创建约束,使其左右与表视图相等,优先级为 UILayoutPriorityDefaultHigh。当 header 视图移动到 didMoveToWindow: 中的 non-nil window 时,我将这些约束添加到 tableView: 并在 willMoveToSuperview 中将其从其超级视图中删除时删除它们。设置完成后,我使用 systemLayoutSizeFittingSize 但传入 self.frame,然后将其设置为 tableHeaderView。

这似乎工作正常,包括旋转。 adding/removing 约束的顺序对于避免 UILayout 发出警告非常重要。

找到解决方案。

简而言之,约束没问题,在 iOS 8 上,systemLayoutSizeFittingSize:UILayoutFittingCompressedSize 按预期工作,但在 iOS7 上没有。

纯属巧合,我调用了

的组合
[self.HeaderView setNeedsLayout];
[self.HeaderView layoutIfNeeded];

两次,我注意到 systemLayoutSizeFittingSize:UILayoutFittingCompressedSize 也以这种方式在 iOS 7 上工作。

在那一刻我意识到解决方案是按顺序调用上面的组合两次(在 iOS 8 上不需要)

最好理解为什么...