如何在启用自动布局的情况下根据 UILabel 的内容自动更改 UILabel 对象的高度和下方其他元素的位置
Posted
技术标签:
【中文标题】如何在启用自动布局的情况下根据 UILabel 的内容自动更改 UILabel 对象的高度和下方其他元素的位置【英文标题】:How to automatically change height of UILabel object and position of other elements below, based on the content of UILabel, with autolayout enabled 【发布时间】:2015-01-17 22:55:30 【问题描述】:我找到了一些与此主题相关的答案,但对我没有任何帮助。我试过setPreferredMaxLayoutWidth:
,将行数设置为0,设置高度约束
到 XYZ,或者等于或大于 XYZ……以及所有这些以许多不同的组合。什么可能是错的?有什么想法吗?
选中的标签是需要根据内容改变高度的标签。标签在其下方,如果标签的内容不适合 1 行,则下方可能的其他元素应向下移动。 IB没有报告约束问题。
【问题讨论】:
如果您分享您的基本设置会有所帮助。如果您的视图很简单,也许您可以分享 Xcode 的屏幕截图,显示您在标签和其他视图上创建的约束。 【参考方案1】:这是我刚刚成功完成的方法:
-
我将标签上的
numberOfLines
设置为0,因此它会根据需要增长和缩小。
我给容器边距添加了标签>= 0
左右前导/尾随空间限制,因此它可以增长到最大宽度。
我确实没有在标签上设置任何高度限制。因此,高度将由内容决定。
我确保标签下方没有任何垂直限制限制其向下增长。
特别要记住,如果您设置从任何位置到屏幕底部的约束,您需要确保其优先级(或从标签到bottom) 的优先级低于标签的垂直Content Compression Resistance Priority。这将确保标签内容的增长能够克服其他垂直限制。
【讨论】:
哦,不。我忘了提到我在滚动视图中拥有所有这些,并且整个页面的大小也必须调整大小...... @Michael “整页”到底是什么? 我发布的视图截图在滚动视图内部,因为该视图在垂直方向上太大了,并且它的高度可能会根据标签的内容而有所不同 @Michael 好吧,我认为这不会对解决方案产生太大影响——您仍然只需要确保没有任何东西将标签的高度限制在更高的位置优先于抗压性。如果您遇到具体问题,请更新问题并提供更多详细信息。 是的,我也这么认为,但它不起作用,也许我缺少一些东西......基本上,所有元素之间的所有垂直约束都应该具有最高优先级,并且它们的父视图应该有垂直内容压缩阻力优先级相同的值,对吧?【参考方案2】:如果您在代码中使用自动布局,则设置框架不起作用。您必须创建所需布局所需的约束集。对于这种情况,您需要为您的 UILabel 添加高度限制。
完整教程在这里:http://www.thinkandbuild.it/learn-to-love-auto-layout-programmatically/
【讨论】:
【参考方案3】:如果您想尝试在代码中处理它,那么您可以这样处理它。我已经布置了类似于您所拥有的东西,然后在 5 秒后它将交换一个新的垂直约束以使其中一个标签更高。希望它能引导您朝着正确的方向前进……或者至少是一个方向!
NSArray * vertConstraint;
UIImageView * imageView = [[UIImageView alloc] init];
UILabel * labelOne = [[UILabel alloc] init];
UILabel * labelTwo = [[UILabel alloc] init];
UILabel * labelThree = [[UILabel alloc] init];
imageView.backgroundColor = [UIColor grayColor];
labelOne.backgroundColor = [UIColor redColor];
labelTwo.backgroundColor = [UIColor blueColor];
labelThree.backgroundColor = [UIColor orangeColor];
[imageView setTranslatesAutoresizingMaskIntoConstraints: NO];
[labelOne setTranslatesAutoresizingMaskIntoConstraints: NO];
[labelTwo setTranslatesAutoresizingMaskIntoConstraints: NO];
[labelThree setTranslatesAutoresizingMaskIntoConstraints: NO];
[self.view addSubview:imageView];
[self.view addSubview:labelOne];
[self.view addSubview:labelTwo];
[self.view addSubview:labelThree];
id topGuide = self.topLayoutGuide;
id bottomGuide = self.bottomLayoutGuide;
NSDictionary * viewsDictionary = NSDictionaryOfVariableBindings(imageView, labelOne,labelTwo,labelThree,topGuide, bottomGuide);
// initial vertical constraints. will be swapped out after 5 seconds (See below
vertConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[topGuide]-100-[imageView(==200)]-20-[labelOne(==20)]-20-[labelTwo(==20)]-20-[labelThree(==20)]-(>=5)-[bottomGuide]|" options:0 metrics: 0 views:viewsDictionary];
[self.view addConstraints:vertConstraint];
// horizontal constraints for all the elements
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(>=0)-[imageView(==200)]-(>=0)-|" options:0 metrics: 0 views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(>=0)-[labelOne(==200)]-(>=0)-|" options:0 metrics: 0 views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(>=0)-[labelTwo(==200)]-(>=0)-|" options:0 metrics: 0 views:viewsDictionary]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-(>=0)-[labelThree(==200)]-(>=0)-|" options:0 metrics: 0 views:viewsDictionary]];
//additional constraints to center them
[self.view addConstraint:
[NSLayoutConstraint constraintWithItem:imageView
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
[self.view addConstraint:
[NSLayoutConstraint constraintWithItem:labelOne
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
[self.view addConstraint:
[NSLayoutConstraint constraintWithItem:labelTwo
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
[self.view addConstraint:
[NSLayoutConstraint constraintWithItem:labelThree
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self.view
attribute:NSLayoutAttributeCenterX
multiplier:1
constant:0]];
//delay 5 seconds then swap out vertical constraints
// in this case change the (==20) to (==40) for height of element
// you can edit that string more dynamically to fit your needs
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 5 * NSEC_PER_SEC), dispatch_get_main_queue(), ^
NSArray * newVertConstraint = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[topGuide]-100-[imageView(==200)]-20-[labelOne(==20)]-20-[labelTwo(==40)]-20-[labelThree(==20)]-(>=5)-[bottomGuide]|" options:0 metrics: 0 views:viewsDictionary];
[self.view removeConstraints:vertConstraint];
[self.view addConstraints:newVertConstraint];
[self.view setNeedsUpdateConstraints];
[UIView animateWithDuration:1.5 animations:^
[self.view layoutIfNeeded];
];
);
【讨论】:
以上是关于如何在启用自动布局的情况下根据 UILabel 的内容自动更改 UILabel 对象的高度和下方其他元素的位置的主要内容,如果未能解决你的问题,请参考以下文章
如何使用自动布局在 iOS 中根据文本长度更改 UILabel 宽度
无法在自动布局“打开”的情况下移动 UILabel 的 Y 位置
如何设置自动布局,以便 UILabel 调整大小并根据需要移动其他视图