Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/114.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 一个接一个地放置视图_Ios_Iphone_Objective C_View - Fatal编程技术网

Ios 一个接一个地放置视图

Ios 一个接一个地放置视图,ios,iphone,objective-c,view,Ios,Iphone,Objective C,View,我有一个视图控制器,它有一系列子视图。这些子视图是一个接一个垂直放置的自定义UI视图。子视图的高度不一致;它们的高度基于实例化它们时使用的数据。此外,我希望支持设备旋转,以便子视图的UILabel在横向模式下水平扩展,并且更短 我很难以一种好的方式完成这项任务。当视图控制器布置它的子视图时,我觉得我没有明确的方法来计算每个子视图的高度(因为我在这里实例化了它们,但没有设置它们的帧)。请参考我下面的代码来理解我的沮丧 如果子视图的

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

我很难以一种好的方式完成这项任务。当视图控制器布置它的子视图时,我觉得我没有明确的方法来计算每个子视图的高度(因为我在这里实例化了它们,但没有设置它们的帧)。请参考我下面的代码来理解我的沮丧

如果子视图的
方法在视图控制器的
方法之前被调用,我非常希望这样做,但事实并非如此

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

我正在根据下面的评论进行编辑和总结:

以下是调用这些方法的顺序:

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]
最好的方法是将尺寸代码从视图的LayoutSubView中取出,并将其放入单独的视图方法(可能是mySize)中,然后从ViewWillLayoutSubView中的viewcontroller调用该方法,也可以从视图的LayoutSubView调用该方法(这样就不会有重复的代码)

这可能就是它的样子(viewWillLayoutSubviews正在调用所有子视图的mySize方法):


顺便说一句,如果您在viewcontroller中更改子视图的框架,它将触发子视图上的needsLayout,以及最终的LayoutSubview。

那么它们在视图中没有正确对齐有什么问题呢?按照上面的编码方式,所有的子视图都是相互重叠的,我做了一个很简单的方法,在子视图中有一个calculateHeight方法,它可以做一些逻辑来计算出子视图的高度……我觉得这绝对不是正确的方法,因为这项工作已经在子视图的layoutSubviews方法1中完成了。没有
[self.view addSubview:…]
。是否将这些视图添加为子视图?2.您可以在
layoutSubview
方法中对它们进行布局。3.如果要计算内部子视图的大小,可以重写
sizeThatFits:
,并以这种方式返回正确的大小。然后,在布局子视图中就不会出现问题。首先将当前高度更改为cgfloat或float类型,以及您使用的所有int变量我会在viewDidLoad中添加子视图,我会在LayoutSubView中设置框架,正如您在上面的代码中所看到的那样。viewDidLoad在调用其他方法之前被调用。但是,视图控制器的子视图数组…只有在视图控制器的viewWillLayoutSubviews之后才会调用其layoutSubviews方法。然而,在viewWillLayoutSubviews方法中,我需要知道子视图的高度——我从在layoutSubviews中布局它们得到的高度……我想我一直误解了你。为什么您认为viewWillLayoutSubviews应该在layoutSubviews之前被调用?据我所知,viewWillLayoutSubviews会提前警告您将调用layoutSubviews。在ViewWillLayoutSubView中需要值有什么原因吗?是否可以跳过viewWillLayoutSubviews,只在layoutSubviews中执行所有操作?对于视图控制器不知道的自身帧大小,子视图知道什么?如果视图基于它知道的值来创建自己的框架,为什么不在视图类中提供一个viewcontroller可以调用的方法,以获得它需要的大小,然后在viewcontroller的LayoutSubView中,可以设置所有视图的所有框架。在viewController中实现布局子视图。理论上,调用viewWillLayoutSubviews后,每个视图都会调用其layoutSubviews,最后调用viewController的layoutSubviews。因此,要在ViewWillLayoutSubView中执行的操作,可以在视图控制器的LayoutSubView中执行。使用一些日志来查看调用的顺序是否如我所期望的那样。
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]