我做了一个容器视图,我调用了SimpleStackView。这个想法很简单,任何子视图都堆叠在彼此之上。 SimpleStackView的宽度决定了它的子视图的宽度,SimpleStackView的高度由其子视图的高度决定。
我在layoutSubviews中执行此操作,其中我在每个子视图上调用sizeThatFits并使用返回的高度将它们布置在彼此之上。这些高度的总和还决定了从sizeThatView的sizeThatFits重写和intrinsicContentSize重写返回的内容。
我支持iOS 7,因此我无法使用UIStackView。
我使用AutoLayout来布局应用中的大部分内容。我的SimpleStackView在许多地方工作得很好,其中使用AutoLayout在其他视图旁边布局(我依靠其intrinsicContentSize来定义它的高度,没有高度限制),除了在一个将SimpleStackView放在UITableViewCell的contentView中的情况下UITableView的。在这种情况下,触发无限循环。我不是AutoLayout大师。我可能会遗漏一些关于如何在AutoLayout中使用intrinsicContetSizes的内容?这可能是什么情况?我如何正确使用intrinsicContentSize,以便它在所有情况下都能正常工作?
SimpleStackView的代码相对较短;这是完整的类实现:
@implementation SimpleStackView
@synthesize rowSpacing=_rowSpacing;
- (void)layoutSubviews
{
[super layoutSubviews];
[self sizeToFit];
[self invalidateIntrinsicContentSize];
CGFloat nextRowTop = 0;
for (UIView *view in self.subviews)
{
CGSize size = [view sizeThatFits:CGSizeMake(self.bounds.size.width, view.bounds.size.height)];
view.frame = CGRectMake(0, nextRowTop, self.bounds.size.width, size.height);
nextRowTop += view.frame.size.height + self.rowSpacing;
}
}
- (CGSize)sizeThatFits:(CGSize)size
{
CGFloat sumOfHeights = 0;
for (UIView *view in self.subviews) {
sumOfHeights += [view sizeThatFits:CGSizeMake(size.width, view.bounds.size.height)].height;
}
CGFloat sumOfRowSpacings = MAX(0, (int)self.subviews.count - 1) * self.rowSpacing;
return CGSizeMake(size.width, sumOfHeights + sumOfRowSpacings);
}
- (CGSize)intrinsicContentSize
{
CGFloat intrinsicHeight = [self sizeThatFits:self.bounds.size].height;
return CGSizeMake(UIViewNoIntrinsicMetric, intrinsicHeight);
}
// i tried this to fix the infinite loop; didnt work was still stuck in infinite loop
//- (void)setFrame:(CGRect)frame
//{
// CGRect frameBefore = self.frame;
// [super setFrame:frame];
// if (NO == CGRectEqualToRect(frameBefore, frame))
// [self invalidateIntrinsicContentSize];
//}
@end
编辑:我忘了提;导致无限循环的UITableCellView具有从contentView顶部到contentView底部的完整约束链。当我删除其中一个约束来打破链时,无限循环停止发生。我想保留约束,当行高很小时(在UITableViewDelegate的heightForRowAtIndexPath中设置),它们可以压缩多行UILabel。