0

我有一个视图控制器,它有一组子视图。这些子视图是一个接一个垂直放置的自定义 UIView。子视图的高度不一致;它们的高度基于实例化它们时使用的数据。此外,我想支持设备旋转,以便子视图的 UILabels 将在横向模式下水平扩展并且更短。

我在以一种好的方式实现这一点时遇到了很多麻烦。当视图控制器布置它的子视图时,我觉得我没有明确的方法来确定每个子视图的高度(因为我此时已经实例化了它们,但没有设置它们的框架)。请参阅下面的代码以了解我的挫败感。

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;
    }
}
4

1 回答 1

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]

顺便说一句,如果您从视图控制器中更改子视图的框架,它将触发子视图上的需求布局,以及最终的 layoutSubviews。

于 2013-10-24T06:25:57.727 回答