ios - sizeToFit 依赖 layoutSubviews 如何实现?

标签 ios cocoa-touch uiview

layoutSubviews 的文档中,苹果说:

You should not call this method directly.

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

最佳答案

不应覆盖 -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)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);
}

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

虽然可以很容易地调整其他布局样式的代码。

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

相关文章:

ios - 在 iOS 8 中屏幕录制视频崩溃

ios - 快速检测应用程序是在后台还是在前台

iphone - 无法显示带有文本字段的 UIAlertView

objective-c - 如何制作一组常量,以提高方法的可用性?

iphone - 应用 UIView 变换后查找帧坐标 (CGAffineTransform)

ios - 通过 jenkins 在 mac mini 上运行 ios 时获取 java.lang.InterruptedException

ios - 在 XCode 5 中应用程序窗口预计在应用程序启动结束时有一个 Root View Controller

ios - 无法在 View Controller 中创建 socket /操作

objective-c - 如何创建水平 UIPickerView 样式控件?

iphone - UIView 和 XIB 连接。正在显示吗?