我已经找了一整天了,但没能成功。
我有一个UIView
有两个标签,位于另一个标签之上,位于左侧,一个按钮位于右侧。我添加了约束让 autolayout
相应地调整 View 大小。当我为 UIView
的高度设置一个约束时,一切都运行良好。 (并且两个 UILabel
的高度没有任何限制),但作为较低的 UILabel
的内容会有所不同,我删除了该约束并为 UILabel
设置了两个约束,一个固定为鞋面UILabel
和一个具有“大于或等于”关系的较低 UILabel
,与其他一个固定下部之间的距离UILabel
和 UIView
.
看起来自动布局无法计算 intrinsicContentSize
下层UILabel
,因为它永远不会将其高度增加到 10px 以上,尽管较低 UILabel
的内容.
UIView *miView = [[UIView alloc] init];
UILabel *miLabel = [[UILabel alloc] init];
[miLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[miDetailsLabel setNumberOfLines:1];
[miDetailsLabel setText:@"Just one line."];
[miView addSubview:miLabel];
UILabel *miDetailsLabel = [[UILabel alloc] init];
[miDetailsLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[miDetailsLabel setNumberOfLines:0];
[miDetailsLabel setText:@"Enough text to show 3 lines on an IP4, except first of three UILabels on my test code, with no content"];
[miView addSubview:miDetailsLabel];
UIButton *miButton = [[UIButton alloc] init];
[miButton setTranslatesAutoresizingMaskIntoConstraints:NO];
[miView addSubview:miButton];
NSArray *constraint_inner_h = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(0)-[label]-(10)-[button(52)]-(0)-|" options:0 metrics:nil views:@{@"label":miLabel, @"button":miButton}];
NSArray *constraint_inner2_h = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(0)-[details]-(10)-[button]-(0)-|" options:0 metrics:nil views:@{@"details":miDetailsLabel, @"button":miButton}];
NSArray *constraint_label_v = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(0)-[label(18)]-(2)-[details(>=10)]-(0)-|" options:0 metrics:nil views:@{@"label":miLabel, @"details":miDetailsLabel}];
NSArray *constraint_button_v = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[button(22)]" options:0 metrics:nil views:@{@"button":miButton}];
[miView addConstraint:[NSLayoutConstraint constraintWithItem:miButton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:miView attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
[miView addConstraints:constraint_inner_h];
[miView addConstraints:constraint_inner2_h];
[miView addConstraints:constraint_label_v];
[miView addConstraints:constraint_button_v];
我已经放置了代码的简化版本。
对我缺少的东西有什么想法吗?
谢谢
更新:感谢马特的建议,我已经尝试过此解决方案将正确的值设置为 preferredMawLayoutWidth:
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
NSArray *allKeys = [dictOpcionesTickets allKeys];
for (NSString *key in allKeys) {
NSArray *tmpArray = [dictOpcionesTickets objectForKey:key];
if (![[tmpArray objectAtIndex:0] isEqual:@""]) {
UILabel *tmpLabel = [tmpArray objectAtIndex:3];
tmpLabel.preferredMaxLayoutWidth = tmpLabel.frame.size.width;
NSLog(@"width: %f",tmpLabel.frame.size.width);
}
}
[self.view layoutIfNeeded];
}
为了解释代码,正如我所说,我是动态执行的,因此我创建了一个带有数组的字典,其中包含对我的 UILabel
的引用(以及其他有趣的信息)。当我运行代码时,我得到下一个日志(代码解析 3 UILabel
,第一个标签没有内容):
2014-12-28 20:40:42.898 myapp[5419:60b] width: 0.000000
2014-12-28 20:40:42.912 myapp[5419:60b] width: 0.000000
2014-12-28 20:40:43.078 myapp[5419:60b] width: 229.000000
2014-12-28 20:40:43.080 myapp[5419:60b] width: 229.000000
2014-12-28 20:40:43.326 myapp[5419:60b] width: 229.000000
2014-12-28 20:40:43.327 myapp[5419:60b] width: 229.000000
但我仍然得到相同的结果...UIView 仍然显示的高度等于约束设置的最小高度,而不显示 UILabel
的内容.
更新2仍在闲逛。
我已经测试了我的初始代码,但在 xcode 6 中的一个新项目上进行了简化,在装有 iOS7 的实际 iPhone 4 上运行,并且无需设置 preferredMaxLayoutWidth
即可完美运行。或子类化UILabel
,甚至没有打电话 layoutIfNeeded
在父 View 上。但当涉及到真正的项目时(我认为它最初是在 xcode 4 或 5 中构建的),它不起作用:
- (void)addLabelsDinamically {
self.labelFixed.text = @"Below this IB label goes others added dinamically...";
UIButton *miBoton = [[UIButton alloc] init];
miBoton.translatesAutoresizingMaskIntoConstraints = NO;
[miBoton setTitle:@"Hola" forState:UIControlStateNormal];
[self.viewLabels addSubview:miBoton];
[self.viewLabels addConstraint:[NSLayoutConstraint constraintWithItem:miBoton attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.viewLabels attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0.0]];
[self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[boton(22)]" options:0 metrics:nil views:@{@"boton":miBoton}]];
[self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[boton(40)]" options:0 metrics:nil views:@{@"boton":miBoton}]];
UILabel *miLabel = [[UILabel alloc] init];
miLabel.translatesAutoresizingMaskIntoConstraints = NO;
miLabel.backgroundColor = [UIColor redColor];
miLabel.numberOfLines = 0;
miLabel.text = @"ñkhnaermgñlkafmbñlkadnlñejtnhalrmvlkamnñnañorenoetñnngñsdbmnñgwn";
[self.viewLabels addSubview:miLabel];
[self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(8)-[label]-(10)-[boton]-(8)-|" options:0 metrics:nil views:@{@"label":miLabel,@"boton":miBoton}]];
[self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previous]-(8)-[label]" options:0 metrics:nil views:@{@"label":miLabel,@"previous":self.labelFixed}]];
UIView *pre = miLabel;
miLabel = [[UILabel alloc] init];
miLabel.translatesAutoresizingMaskIntoConstraints = NO;
miLabel.backgroundColor = [UIColor greenColor];
miLabel.numberOfLines = 0;
miLabel.text = @"ñkhnaermgñlkafmbñlkadnlñejtnhalrmvlkamnñnañorenoetñnngñsdbmnñgwn";
[self.viewLabels addSubview:miLabel];
[self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(8)-[label]-(10)-[boton]-(8)-|" options:0 metrics:nil views:@{@"label":miLabel,@"boton":miBoton}]];
[self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previous]-(8)-[label]" options:0 metrics:nil views:@{@"label":miLabel,@"previous":pre}]];
}
啊,同一个屏幕上我有一个UILabel
在 IB 上添加了 numberOfLines
设置为“0”,垂直约束“大于或等于”,水平约束以类似的方式设置(但两个约束都设置在 IB 上)......而且它工作得很好......这让我发疯!有什么帮助吗???
最佳答案
好吧,最后我发现了错误,正如我在“更新2”中所说的那样,很奇怪的是它正在通过IB添加的UILabel
上工作,但不适用于那些添加的动态地。
所以,我再次查看IB上的屏幕,发现我有一个具有“等于”关系的高度约束,当我将其更改为“大于或等于”时,一切都开始起作用了!为什么我没有注意到约束不是“大于或等于”?因为当我添加带有标签的 View 时,带有约束的 View 变得越来越大。这是一个错误吗?
好吧,如果有人觉得这有用的话,总结一下。 “如何添加UILabel
适应其内容的多行?”
在iOS 6版本中,这是一个“preferredMaxLayoutWidth
”的错误,一旦“布局”后就无法获取宽度,因此程序员必须设置通过代码(最好的解决方案是动态地执行它,我将其放在上面的问题中的一个例子)。
幸运的是,在 iOS7 及更高版本上,这个问题已得到解决,您只能在有约束的情况下依赖。
通过IB添加
- 添加
UILabel
,并将“行数”设置为“0”(这将使UILabel
使用所需的行数)。 - 添加约束,您至少需要 3 个约束(固定到顶部或底部,以及两侧),第四个约束是具有“大于或等于”关系的高度。
- 确保 View 容器有足够的空间,或者还具有“大于或等于”关系的高度约束。
- 添加
通过代码添加(只需粘贴上面发布的代码):
UILabel *miLabel = [[UILabel alloc] init]; // Initialitze the UILabel miLabel.translatesAutoresizingMaskIntoConstraints = NO; // Mandatory to disable old way of positioning miLabel.backgroundColor = [UIColor redColor]; miLabel.numberOfLines = 0; // Mandatory to allow multiline behaviour miLabel.text = @"ñkhnaergñsdbmnñgwn"; // big test to test [self.viewLabels addSubview:miLabel]; // Add subview to the parent view [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[label]-(10)-|" options:0 metrics:nil views:@{@"label":miLabel}]]; // horizontal constraint [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-(10)-[label]" options:0 metrics:nil views:@{@"label":miLabel}]]; UIView *pre = miLabel; // Adding a second label to test the separation miLabel = [[UILabel alloc] init]; miLabel.translatesAutoresizingMaskIntoConstraints = NO; miLabel.backgroundColor = [UIColor greenColor]; miLabel.numberOfLines = 0; miLabel.text = @"ñkhnaermgñlkafmbnoetñnngñsdbmnñgwn"; [self.viewLabels addSubview:miLabel]; [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(10)-[label]-(10)-|" options:0 metrics:nil views:@{@"label":miLabel,@"boton":miBoton}]]; [self.viewLabels addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previous]-(10)-[label]" options:0 metrics:nil views:@{@"label":miLabel,@"previous":pre}]];
感谢那些试图帮助我的人!这个网站太棒了:)
关于ios - 如何以编程方式添加具有可变高度和布局 ios 的 UILabel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27678850/