intrinsicContentSize在特殊情况

时间:2016-05-31 09:04:15

标签: ios autolayout

我做了一个容器视图,我调用了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。

0 个答案:

没有答案