ios iOS如何根据其中的UILabel制作UIView的动态宽度/自动布局
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24438044/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
iOS how to make dynamic width / autolayout of UIView according to UILabel within it
提问by kalafun
I am struggling with maybe a bit of a rookie issue. I have a UIView
within which I display some price. I want the UIView
to be of a dynamic width according to the price, if its 1 Euro, then it will be e.g. 20pt
, if its 2300 Euro, then it will be like 50pt
in width.
我正在为一个新手问题而苦苦挣扎。我有一个我UIView
在其中显示一些价格。我希望UIView
根据价格具有动态宽度,如果它是 1 欧元,那么它将是例如20pt
,如果它是 2300 欧元,那么它将像50pt
宽度一样。
I was trying to use the storyboard's constraints but without luck. Is it possible to do it within storyboard or do I have to calculate the width of UILabel
and then set the width of UIView
programmatically?
我试图使用故事板的约束,但没有运气。是否可以在故事板中进行,或者我是否必须计算宽度UILabel
然后以UIView
编程方式设置宽度?
Thank you in advance.
先感谢您。
回答by rdelmar
Yes, you can do this in the storyboard. Add a label to your view and pin it to the left and right edge (top and bottom if you want also). Give the view constraints to its superview in the x and y directions, but do not give it a width constraint (it will need a height constraint if you didn't pin the top and bottom of the label to it). The view should then expand with the label depending on its content.
是的,您可以在故事板中执行此操作。将标签添加到您的视图并将其固定到左右边缘(如果需要也可以是顶部和底部)。在 x 和 y 方向为它的父视图提供视图约束,但不要给它一个宽度约束(如果你没有将标签的顶部和底部固定到它上面,它将需要一个高度约束)。然后,视图应根据其内容使用标签展开。
回答by user3386109
In general, auto layout is performed in a top-down fashion. In other words, a parent view layout is performed first, and then any child view layouts are performed. So asking the system to size the parent based on the child is a bit like swimming upstream, harder to do, but still possible with some work.
通常,自动布局以自顶向下的方式执行。换句话说,首先执行父视图布局,然后执行任何子视图布局。因此,要求系统根据子项来确定父项的大小有点像逆流而上,很难做到,但仍然可以通过一些工作来实现。
One solution is to use the intrinsic sizeof a view.
一种解决方案是使用本征尺寸的视图。
For example, a UILabel
has an intrinsic size based on the text in the label. If a UILabel
has a leading constraint and a top constraint, but no other constraints, then its width and height are determined by its intrinsic size.
例如, aUILabel
具有基于标签中文本的固有大小。如果 aUILabel
具有前导约束和顶部约束,但没有其他约束,则其宽度和高度由其固有大小决定。
You can do the same thing with a custom view class that encloses a UILabel. By setting the intrinsic size of the custom view class based on the intrinsic size of the UILabel, you get a view that automatically resizes based on the text in the label.
您可以使用包含 UILabel 的自定义视图类执行相同的操作。通过根据 UILabel 的固有大小设置自定义视图类的固有大小,您将获得一个根据标签中的文本自动调整大小的视图。
Here's what the code looks like for the custom class. The .h
file defines a single property text
. The .m
file has an IBOutlet to the child label. Setting and getting the text
property simply sets or gets the text from the label. But there's one very important twist, setting the text invalidates the intrinsic size of the parent. That's what makes the system adjust the size of the parent view. In the sample code below the parent is sized to have an 8 pixel margin all around the UILabel.
下面是自定义类的代码。该.h
文件定义了一个属性text
。该.m
文件具有到子标签的 IBOutlet。设置和获取text
属性只是设置或获取标签中的文本。但是有一个非常重要的转折,设置文本会使父级的内在大小无效。这就是让系统调整父视图大小的原因。在下面的示例代码中,父级被调整为在 UILabel 周围有 8 像素的边距。
SurroundView.h
环视.h
@interface SurroundView : UIView
@property (strong, nonatomic) NSString *text;
@end
SurroundView.m
环视.m
@interface SurroundView()
@property (weak, nonatomic) IBOutlet UILabel *childLabel;
@end
@implementation SurroundView
- (void)setText:(NSString *)text
{
self.childLabel.text = text;
[self invalidateIntrinsicContentSize];
}
- (NSString *)text
{
return( self.childLabel.text );
}
- (CGSize)intrinsicContentSize
{
CGSize size = self.childLabel.intrinsicContentSize;
size.height += 16;
size.width += 16;
return( size );
}
@end
Creating the IBOutlet to the childLabel
can be a little tricky, so here's the procedure
为 IBOutlet 创建 IBOutletchildLabel
可能有点棘手,所以这里是过程
- drag out a UIView into the storyboard
- use the Identity inspector to change the class to
SurroundView
- drag out a UILabel and add it as a subview of the
SurroundView
- select the label, and open the assistant editor
- show
SurroundView.m
in the assistant - drag from the open circle to the label as shown below
- 拖出一个 UIView 到故事板中
- 使用身份检查器将类更改为
SurroundView
- 拖出一个 UILabel 并将其添加为
SurroundView
- 选择标签,然后打开助理编辑器
SurroundView.m
在助手中显示- 从空心圆拖动到标签,如下所示
All that's left is to get the constraints right. The constraints for the label should look like this
剩下的就是让约束正确。标签的约束应该是这样的
The constraints for the SurroundView
should be as shown below. The key point is that the Intrinsic Sizeshould be set to Placeholderto avoid the warnings about missing constraints.
的约束SurroundView
应如下所示。关键是应将Intrinsic Size设置为Placeholder以避免有关缺少约束的警告。
回答by NavinDev
Place the label inside the view and pin its TOP , BOTTOM , TRAILING and LEADING edges to the labels superview. Note that you do not specify the width constraint. Now add a height and width constraint to the view. Make an outlet to the width constraint and when the price changes set the view's width constraint's constant to your desired value. Since the label is pinned to the view it will expand too.
将标签放置在视图内,并将其 TOP 、 BOTTOM 、 TRAILING 和 LEADING 边缘固定到标签超级视图。请注意,您没有指定宽度约束。现在向视图添加高度和宽度约束。为宽度约束做一个出口,当价格发生变化时,将视图的宽度约束常量设置为您想要的值。由于标签固定在视图上,它也会展开。