我有一个视图控制器,它有一个子视图数组。这些子视图是垂直放置的自定义UIViews。子视图的高度不一致;它们的高度基于实例化时使用的数据。另外,我想支持设备旋转,以便子视图的UILabel在横向模式下水平扩展并缩短。
我在很好地完成这项工作时遇到了很多麻烦。当视图控制器正在布置它的子视图时,我觉得我没有干净的方法来确定每个子视图的高度(因为我此时已经实例化了它们,但没有设置它们的帧)。请参考下面的代码来了解我的挫败感。
如果在视图控制器的 layoutSubviews
方法之前调用了子视图的 viewWillLayoutSubviews
方法,我真的很喜欢它事实并非如此。
MyViewController.m
....
- (void)initWithDataObjects:(NSArray*)dataObjects
{
_dataObjects = dataObjects;
}
- (void)viewDidLoad
{
mySubviews = [[NSMutableArray alloc] init];
for (DataObject* do in _dataObjects) {
MyCustomView *customView = [[MyCustomView alloc] initWithDataObject:do];
[mySubviews addObject:customView];
[self.view addSubview:customView];
}
}
- (void)viewWillLayoutSubviews
{
int currentHeight = 0;
for (MyCustomView *customView in mySubviews) {
int subviewHeight = customView.frame.size.height;
// PROBLEM: subviewHeight is 0 because the subview hasn't called layoutSubviews yet..
[customView setFrame:CGRectMake(0, currentHeight, self.view.frame.size.width, subviewHeight)];
currentHeight += subviewHeight;
}
}
答案 0 :(得分:1)
我正在根据以下评论进行编辑和总结:
以下是调用这些方法的顺序:
2013-10-24 01:05:11.391 MyTestApp[34166:70b] -[MyViewController viewDidLoad]
2013-10-24 01:05:11.395 MyTestApp[34166:70b] -[MyViewController addMySubViews]
2013-10-24 01:05:11.395 MyTestApp[34166:70b] -[view1 didMoveToSuperview]
2013-10-24 01:05:11.395 MyTestApp[34166:70b] -[view2 didMoveToSuperview]
2013-10-24 01:05:11.395 MyTestApp[34166:70b] -[view3 didMoveToSuperview]
2013-10-24 01:05:11.398 MyTestApp[34166:70b] -[MyViewController viewWillLayoutSubviews]
2013-10-24 01:05:11.398 MyTestApp[34166:70b] -[MyViewController viewDidLayoutSubviews]
2013-10-24 01:05:11.398 MyTestApp[34166:70b] -[view1 layoutSubviews]
2013-10-24 01:05:11.398 MyTestApp[34166:70b] -[view2 layoutSubviews]
2013-10-24 01:05:11.398 MyTestApp[34166:70b] -[view3 layoutSubviews]
您最好的选择是从视图的layoutSubviews中取出您的大小调整代码,并将其放在单独的视图方法(可能是mySize)中,并从viewWillLayoutSubviews中的viewcontroller调用该方法,您也可以从视图的layoutSubviews中调用它(所以你没有重复的代码)。
这可能是它的样子(viewWillLayoutSubviews正在调用所有子视图的'mySize方法):
2013-10-24 01:38:10.501 MyTestApp[34850:70b] -[MyViewController viewDidLoad]
2013-10-24 01:38:10.501 MyTestApp[34850:70b] -[MyViewController addMySubViews]
2013-10-24 01:38:10.501 MyTestApp[34850:70b] -[view1 didMoveToSuperview]
2013-10-24 01:38:10.501 MyTestApp[34850:70b] -[view2 didMoveToSuperview]
2013-10-24 01:38:10.502 MyTestApp[34850:70b] -[view3 didMoveToSuperview]
2013-10-24 01:38:24.396 MyTestApp[34850:70b] -[MyViewController viewWillLayoutSubviews]
2013-10-24 01:38:24.396 MyTestApp[34850:70b] -[view1 mySize]
2013-10-24 01:38:24.396 MyTestApp[34850:70b] -[view2 mySize]
2013-10-24 01:38:24.396 MyTestApp[34850:70b] -[view3 mySize]
2013-10-24 01:38:24.397 MyTestApp[34850:70b] -[MyViewController viewDidLayoutSubviews]
2013-10-24 01:38:24.397 MyTestApp[34850:70b] -[view1 layoutSubviews]
2013-10-24 01:38:24.397 MyTestApp[34850:70b] -[view2 layoutSubviews]
2013-10-24 01:38:24.397 MyTestApp[34850:70b] -[view3 layoutSubviews]
顺便说一句,如果你从视图控制器中更改子视图的框架,它将在子视图上触发needsLayout,并最终触发layoutSubviews。