OGeek|极客世界-中国程序员成长平台

标题: ios - 如果 sizeToFit 依赖于 layoutSubviews,如何实现? [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-12 14:49
标题: ios - 如果 sizeToFit 依赖于 layoutSubviews,如何实现?

layoutSubviews 的文档中,苹果说:

You should not call this method directly.

我正在尝试实现 sizeToFit。我希望它在所有 subview 上放置一个紧密的边界框。在确定这样的边界框之前,我必须布局 subview 。这意味着我必须调用 Apple 不赞成的 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
     )
  );
}



Best Answer-推荐答案


不应覆盖 -sizeToFit。而是用 View 的当前边界大小覆盖 -sizeThatFits:,它由 -sizeToFit 内部调用。

You should not override this method. If you want to change the default sizing information for your view, override the sizeThatFits: instead. That method performs any needed calculations and returns them to this method, which then makes the change. – UIView Class Reference


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

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


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

#pragma mark - Layout & Sizing

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

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

    return CGSizeMake(width, height);
}

- (CGFloat)calculateHeightForWidthCGFloat)width applyLayoutBOOL)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);
}

请注意,示例代码适用于可以以任何宽度显示的 View ,并且容器会要求特定宽度的首选高度。

不过,您可以轻松地调整其他布局样式的代码。

关于ios - 如果 sizeToFit 依赖于 layoutSubviews,如何实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29287431/






欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://ogeek.cn/) Powered by Discuz! X3.4