如何在sizeThatFits之前调用layoutSubviews?

时间:2012-08-27 19:35:18

标签: iphone ios cocoa-touch uiview

当我在其中一个视图上调用sizeToFit时,我注意到iOS框架首先在该视图上调用sizeThatFits然后调用layoutSubviews。这对我来说有问题,因为我sizeThatFits中的计算取决于我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
    );
}

5 个答案:

答案 0 :(得分: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之前不依赖于记住调用某个方法,但您的视图将始终按照您的意愿执行。此外,从现在开始几个月(或让不同的开发人员查看),您的代码不那么脆弱且易于理解。

答案 1 :(得分:2)

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

- (CGSize) sizeThatFits:(CGSize)size {

    [self setNeedsLayout];
    [self layoutIfNeeded];

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

更好的方法可能是为子视图使用自动布局,然后使用systemLayoutSizeFittingSize:确定所需的视图大小(与sizeThatFits:对比)

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

答案 2 :(得分:1)

您是否尝试在视图上调用layoutIfNeeded以强制layoutSubviews?尽管名称具有误导性,但这是立即触发layoutSubviews的方法。请尝试在sizeToFitsizeThatFits之前调用此方法。

答案 3 :(得分:1)

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

要解决这个问题,你需要改变逻辑或自己做数学,以获得明确的维度,而不依赖于自动化的东西。

答案 4 :(得分:0)

您是否只能使用-layoutSubviews方法而不是-sizeThatFits:方法更改子视图的框架?