1

从其他堆栈溢出问题中,我了解到在您的视图控制器中,您可以使用viewDidLoad方法来初始化子视图和viewWillLayoutSubviews方法来设置框架。这意味着我们需要保留视图控制器实例中所有视图的引用(如下所示)。这一切都很好,很好,可以处理设备旋转等。

UILabel* myLabel;

- (void)viewDidLoad
{
    myLabel = [[UILabel alloc] init];
    [myLabel setText:@"Hello"];
}

- (void)viewWillLayoutSubviews
{
    [myLabel setFrame:CGRectMake(0, 0, self.view.frame.size.width, 21)];
}

我的问题是,如果您有一个复杂的子视图层次结构怎么办。例如,如果您有一个 UIView 的子视图,并且您向该 UIView 添加子视图(并且可能更深入),该怎么办。您是否必须保留对整个视图层次结构中每个视图的引用,以便在viewWillLayoutSubviews上修改每个视图的框架?这似乎是唯一的方法。约束是最好的方法,这样您就不必经常修改框架吗?构建大量自定义 UIView 以使管理此层次结构在每个自定义视图中更易于管理和自包含的最佳答案是什么?

希望这是一个足够清楚的问题..在此先感谢。

4

2 回答 2

1

每当您以可能更改布局约束的方式操作视图或子视图时,您必须调用

[view layoutSubviews];

这将使用新的属性设置重新制作约束。加载 viewController 时,您将设置所有不处理框架或边界的属性,然后在 viewWillLayoutSubviews 中设置视图的框架,这样就可以制定所有约束并确保它们得到满足。

您放入情节提要中要使用的任何对象都应具有一个属性,该属性将包含对该对象的引用。这是一个很好的编码实践,特别是如果您遵循测试驱动开发的规则。

现在回答您的问题,如果您在情节提要中创建复杂的层次结构,那么只要您的约束条件正常,一切都应该没问题,如果您在代码中创建它,请确保在调用 addSubview 时调用 layoutSubviews 示例:

UIView* view1 = [[UIView alloc] initWithFrame:CGRectZero];
UIView* view2 = [[UIView alloc] initWithFrame:CGRectZero];
[view1 addSubview:view2];
[view1 layoutSubviews];

更多的视图不会使结构更好,但如果你有 100 个子视图......让我们成为现实......有些东西需要在单独的视图中分类......

约束让您可以完美地定义视图框架。一开始您可能不会注意到差异,但如果您将其与 Autoresizing Mask 进行比较,您会发现差异。此外,这里有一个指南,公然向您展示差异。

布局约束和自动布局

于 2013-10-18T18:31:36.700 回答
1

如果您希望划分一些逻辑并重用组件,还值得考虑的是使用子视图控制器。

于 2013-10-19T04:14:03.957 回答