9

当我调用sizeToFit我的一个视图时,我注意到 iOS 框架首先调用sizeThatFits,然后再调用layoutSubviews该视图。这对我来说是有问题的,因为 my 中的计算sizeThatFits取决于 my 的结果layoutSubviews。在下面的例子中,一个子视图被调整layoutSubviews并且这个子视图的高度被用于sizeThatFits. 目前我的代码不起作用,顺序颠倒了。

在我的视图控制器的 viewDidLoad 中:

UIView* header = [[MyHeader alloc] init];
[header sizeToFit];
self.tableView.tableHeaderView = header;
[header release];

在我看来:

- (void) layoutSubviews {
    [super layoutSubviews];
    [self.subView sizeToFit];
}

- (CGSize) sizeThatFits:(CGSize)size {
    return CGSizeMake(
        self.frame.size.width,
        self.subView.frame.size.height
    );
}
4

5 回答 5

6

无论您以何种顺序调用事物,您都希望您的视图始终执行正确的事情(tm)。为此,我建议将计算视图和子视图所需高度的代码放在单独的方法中。这些方面的东西:

- (void)updateSubviewDimensions
{
    [self.subview sizeToFit];
    // possibly much more code
}

- (void) layoutSubviews {
    [super layoutSubviews];
    [self updateSubviewDimensions];
}

- (CGSize) sizeThatFits:(CGSize)size {
    [self updateSubviewDimensions];
    return CGSizeMake(
        self.frame.size.width,
        self.subView.frame.size.height
    );
}

这样,您不必依赖在调用之前记住调用某个方法sizeToFit,但您的视图将始终执行您想要的操作。另外,当您在几个月后查看它时(或让不同的开发人员查看它),您的代码将不那么脆弱并且更容易理解。

于 2013-12-11T17:08:19.647 回答
2

如果您sizeThatFits:要求布局准确,那么您需要强制布局(请参见下面的代码。)但我认为这是设计不佳的,因为您的布局没有考虑“大小”。

- (CGSize) sizeThatFits:(CGSize)size {

    [self setNeedsLayout];
    [self layoutIfNeeded];

    return CGSizeMake(
        self.frame.size.width,
        self.subView.frame.size.height
    );
}

更好的方法可能是为您的子视图使用自动布局,然后用于systemLayoutSizeFittingSize:确定您的视图所需的大小(vs. sizeThatFits:

如果您不能或不想使用自动布局,那么您应该考虑为实际布局和布局计算使用单独的代码路径。

于 2013-12-11T17:19:34.997 回答
1

您是否尝试过调用layoutIfNeeded视图强制layoutSubviews?尽管名称具有误导性,但这是立即触发的方式layoutSubviewssizeToFit尝试在或之前调用它sizeThatFits

于 2013-12-11T16:57:27.037 回答
1

这里的问题是子视图在调用 layoutSubviews 之前没有尺寸。这与自定义表格视图单元格中的相同。

要解决这个问题,您需要更改逻辑或自己进行数学运算以获得明确的维度,而不依赖于自动的东西。

于 2013-12-17T00:52:33.637 回答
0

你不能只在-layoutSubviews方法而不是-sizeThatFits:方法中更改子视图的框架吗?

于 2012-08-27T19:40:44.010 回答