当我在其中一个视图上调用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
);
}
答案 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
的方法。请尝试在sizeToFit
或sizeThatFits
之前调用此方法。
答案 3 :(得分:1)
这里的问题是,在调用layoutSubviews之前,子视图没有尺寸。这与自定义表格视图单元格中的相同。
要解决这个问题,你需要改变逻辑或自己做数学,以获得明确的维度,而不依赖于自动化的东西。
答案 4 :(得分:0)
您是否只能使用-layoutSubviews
方法而不是-sizeThatFits:
方法更改子视图的框架?