如果它依赖于layoutSubviews,如何实现sizeToFit?

JoJ*_*oJo 2 cocoa-touch uiview ios

layoutSubviews的文档中,Apple说:

您不应该直接调用此方法.

我正在努力实施sizeToFit.我希望它在所有子视图上放置一个紧密的边界框.我必须在确定这样的边界框之前布局子视图.这意味着我必须打电话layoutSubviews,苹果皱眉.如何在不违反Apple规则的情况下解决这一难题?

- (void)layoutSubviews
{
  [super layoutSubviews];

  self.view0.frame = something;
  self.view1.frame = somethingElse;
}

- (void)sizeToFit
{
   [self layoutSubviews];

   self.frame = CGRectMake(
     self.frame.origin.x,
     self.frame.origin.y,
     MAX(
       self.view0.frame.origin.x + self.view0.frame.size.width,
       self.view1.frame.origin.x + self.view1.frame.size.width
     ),
     MAX(
       self.view0.frame.origin.y + self.view0.frame.size.height,
       self.view1.frame.origin.y + self.view1.frame.size.height
     )
  );
}
Run Code Online (Sandbox Code Playgroud)

Chr*_*orr 5

一个人不应该覆盖-sizeToFit.而是使用视图的当前边界大小覆盖-sizeThatFits:内部调用的内容-sizeToFit.

您不应该覆盖此方法.如果要更改视图的默认大小调整信息,请改写sizeThatFits:.该方法执行任何所需的计算并将它们返回到此方法,然后进行更改.- UIView类参考


即使您要覆盖也不是这样-sizeToFit,很可能没有理由立即执行布局.您只能调整视图大小,即设置其边界大小.这会触发调用-setNeedsLayout,将视图标记为需要布局.但除非您想要为视图设置动画,否则不必立即应用新布局.

这种延迟更新模式的要点是,如果执行多个连续更新,它会节省大量时间,因为实际更新只执行一次.


我通常这样做.它就像一个魅力.

#pragma mark - Layout & Sizing

- (void)layoutSubviews
{
    [self calculateHeightForWidth:self.bounds.size.width applyLayout:YES];
}

- (CGSize)sizeThatFits:(CGSize)size
{
    CGFloat const width = size.width;
    CGFloat const height = [self calculateHeightForWidth:width applyLayout:NO];

    return CGSizeMake(width, height);
}

- (CGFloat)calculateHeightForWidth:(CGFloat)width applyLayout:(BOOL)apply
{
    CGRect const topViewFrame = ({
        CGRect frame = CGRectZero;
        ...
        frame;
    });

    CGRect const bottomViewFrame = ({
        CGRect frame = CGRectZero;
        ...
        frame;
    });

    if (apply) {
        self.topView.frame = topViewFrame;
        self.bottomView.frame = bottomViewFrame;
    }

    return CGRectGetMaxY(bottomViewFrame);
}
Run Code Online (Sandbox Code Playgroud)

请注意,示例代码用于可以任何宽度显示的视图,容器会询问特定宽度的首选高度.

可以轻松调整其他布局样式的代码.