【发布时间】:2014-02-17 21:07:32
【问题描述】:
所以我设置了一个 UIView,其中包含一个 UIScrollView(和子内容视图),它具有一系列 UILabel 和 UIViews 的子视图,这些子视图根据其中包含的内容而增长和缩小,所有这些都使用 Storyboard 中的 AutoLayout。当我有类似标签 - 标签 - 标签 - 没有任何问题的视图时,这有效,但是如果我在两个标签之间放置一个空 UIView 并在 UIView 上插入子视图,我看不到结果期待。我在情节提要中有以下布局:
...蓝绿色和蓝色视图是增长到无限高度的标签,橙色视图(optionsPanel)是一个空的 UIVIew,我稍后将子视图注入其中。窗口上剩下的东西是 UILabels 和 UISegment 控件。在每一行视图之间,我有一个常量为 8 的垂直空间约束。这一切都很好,直到我不得不放入空的 UIView 并以编程方式注入子视图。我希望工作的代码类似于(optionsPanel 是橙色的 UIView)...
optionsPanel.translatesAutoresizingMaskIntoConstraints = YES;
NSArray *options = [product objectForKey:@"options"];
lastTop = 10;
for(int i=0;i<options.count; i++) {
NSDictionary *option = [options objectAtIndex:i];
NSArray *values = [option objectForKey:@"values"];
if([self hasNoneValue:values] && values.count == 2) {
NSDictionary *value = [self notNoneValue:values];
M13Checkbox *optionCheck = [[M13Checkbox alloc] initWithTitle:[option objectForKey:@"name"]];
optionCheck.frame = CGRectMake(0, lastTop, 280, 25);
[optionsPanel addSubview:optionCheck];
lastTop += 25;
} else {}
}
...橙色的 UIView 会神奇地增长,一切都会相应地被推开,但这就是我所看到的:
...橙色的 UIView 根本没有增长,另外两个顶部的 UIView 已经离开屏幕的某个地方。所以我的下一个猜测是使用...关闭 Autoresizing Mask。
optionsPanel.translatesAutoresizingMaskIntoConstraints = NO;
...但是我得到的结果是,一切似乎都在工作,但橙色的 UIView(optionsPanel)无论出于何种原因都没有高度,看起来像:
这越来越接近我的预期,所以我想我会使用类似的代码强制橙色 UIView 的高度...
frame = optionsPanel.frame;
frame.size.height = lastTop;
optionsPanel.frame = frame;
...但这似乎对任何事情都没有影响。
纯粹是猜测,我发现这段代码几乎可以工作,如果我任意将 optionPanel 的原点设置为比所需空间大得多的东西......
optionsPanel.translatesAutoresizingMaskIntoConstraints = YES;
NSArray *options = [product objectForKey:@"options"];
lastTop = 10;
for(int i=0;i<options.count; i++) {
NSDictionary *option = [options objectAtIndex:i];
NSArray *values = [option objectForKey:@"values"];
if([self hasNoneValue:values] && values.count == 2) {
NSDictionary *value = [self notNoneValue:values];
M13Checkbox *optionCheck = [[M13Checkbox alloc] initWithTitle:[option objectForKey:@"name"]];
optionCheck.frame = CGRectMake(0, lastTop, 280, 25);
[optionsPanel addSubview:optionCheck];
lastTop += 25;
} else {}
}
lastTop += 10;
frame = optionsPanel.frame;
frame.size.height = lastTop;
frame.origin.y += 300; //some arbitrarily large number
optionsPanel.frame = frame;
..这给出了这个结果:
...但显然 AutoLayout 已决定名称标签需要占用额外的空间。这是一种丑陋的方法,但如果我能弄清楚我需要多少空间,那么我可以把所有东西都往下推,如果必须的话。在两个动态大小的标签之间有一个动态 UIView 的秘诀是什么?一切正常???
【问题讨论】:
-
我发现另一个可行的方法是: NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:priceLabel attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:optionsPanel attribute:NSLayoutAttributeTop multiplier:1 constant:lastTop]; constraint.priority = UILayoutPriorityRequired; [contentView addConstraint:constraint];我将定价标签的顶部设置为选项面板的顶部,其中一个常数是选项面板的高度,它将所有内容都向下推。这并不理想,但很有效。
-
其实这不太行,optionsPanel 的高度只有~20 像素,所以其他复选框是不可触摸的。
-
您需要在选项面板和它的子视图之间建立约束关系,以强制选项面板增长以适应内容。你不是免费得到的。当您以编程方式添加子视图时,默认的自动调整大小掩码是
UIViewAutoresizingNone,它本质上是说“保持帧不变”,这转化为自动布局约束根本不会影响超级视图的大小。 -
还要注意第一个屏幕截图中顶层视图右侧的红色图标。该图标告诉您约束存在错误(可能在约束下)。如果您单击该图标,您将获得更详细的说明。
-
所以基本上你希望所有 3 个框的大小都适合它们的内容,每个框之间有 8 像素的垂直空间?
标签: ios objective-c uiview constraints autolayout