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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-31 01:07:34  来源:igfitidea点击:

iOS how to make dynamic width / autolayout of UIView according to UILabel within it

iosautolayout

提问by kalafun

I am struggling with maybe a bit of a rookie issue. I have a UIViewwithin which I display some price. I want the UIViewto 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 50ptin 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 UILabeland then set the width of UIViewprogrammatically?

我试图使用故事板的约束,但没有运气。是否可以在故​​事板中进行,或者我是否必须计算宽度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 UILabelhas an intrinsic size based on the text in the label. If a UILabelhas 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 .hfile defines a single property text. The .mfile has an IBOutlet to the child label. Setting and getting the textproperty 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 childLabelcan 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.min the assistant
  • drag from the open circle to the label as shown below
  • 拖出一个 UIView 到故事板中
  • 使用身份检查器将类更改为 SurroundView
  • 拖出一个 UILabel 并将其添加为 SurroundView
  • 选择标签,然后打开助理编辑器
  • SurroundView.m在助手中显示
  • 从空心圆拖动到标签,如下所示

enter image description here

在此处输入图片说明

All that's left is to get the constraints right. The constraints for the label should look like this

剩下的就是让约束正确。标签的约束应该是这样的

enter image description here

在此处输入图片说明

The constraints for the SurroundViewshould 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以避免有关缺少约束的警告。

enter image description here

在此处输入图片说明

回答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 边缘固定到标签超级视图。请注意,您没有指定宽度约束。现在向视图添加高度和宽度约束。为宽度约束做一个出口,当价格发生变化时,将视图的宽度约束常量设置为您想要的值。由于标签固定在视图上,它也会展开。