iOS如何根据其中的UILabel实现UIView的动态宽度/自适应布局

31

我目前遇到一个初学者问题。我有一个UIView,其中显示了一些价格。我想让UIView的宽度根据价格动态变化,如果是1欧元,宽度将为20pt,如果是2300欧元,则宽度将为50pt。

我尝试使用故事板的约束条件但没有成功。在故事板中是否有可能实现,还是我必须计算UILabel的宽度,然后以编程方式设置UIView的宽度?

提前致谢。

3个回答

37

是的,您可以在Storyboard中完成这项任务。 向视图添加标签并将其固定在左右边缘(如果需要,也可以将其固定在顶部和底部)。 让视图在x和y方向上有与其父视图的约束,但不要给它宽度约束(如果您没有将标签的顶部和底部固定在其上,则需要高度约束)。 视图应该根据其内容扩展标签。


你好@rdelmar,你能帮我解决这个问题吗?http://stackoverflow.com/questions/27103760/applying-autolayout-constraints-to-multiple-objects - Ranjit
@Ranjit,NavinDev已经回答了你的问题,尽管你不应该像我在他的回答评论中所说的那样添加前导约束。 - rdelmar
当你说在X和Y方向上给它的父视图添加限制时,你是指给它任何水平和垂直的限制(相对于它的父视图)吗?谢谢@rdelmar! - Crashalot

27
一般来说,自动布局是从上往下执行的。换句话说,首先执行父视图布局,然后执行任何子视图布局。因此,要求系统根据子视图调整父视图大小有点像逆流而上,虽然需要一些工作,但仍然是可能的。
一种解决方法是使用视图的内在大小。
例如,UILabel基于标签中的文本具有内在大小。 如果UILabel具有前导约束和顶部约束,但没有其他约束,则其宽度和高度由其内在大小确定。
您可以对包含UILabel的自定义视图类执行相同的操作。通过根据UILabel的内在大小设置自定义视图类的内在大小,您可以获得一个根据标签中的文本自动调整大小的视图。
以下是自定义类的代码。 .h文件定义了一个名为text的属性。.m文件具有到子标签的IBOutlet。设置和获取text属性仅简单地设置或获取标签中的文本。但是有一个非常重要的转折,即设置文本会使父级的内在大小无效。这就是使系统调整父视图大小的原因。在以下示例代码中,父级被调整为在UILabel周围具有8像素边距。
SurroundView.h
@interface SurroundView : UIView
@property (strong, nonatomic) NSString *text;
@end

SurroundView.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

IBOutlet用于连接childLabel可能有些棘手,下面是具体步骤:

  • 在Storyboard中拖出一个UIView
  • 使用Identity inspector将类更改为SurroundView
  • 拖出一个UILabel并将其添加为SurroundView的子视图
  • 选择标签,并打开辅助编辑器
  • 在辅助编辑器中显示SurroundView.m
  • 按照下图所示从空心圆拖动到标签上

enter image description here

现在还需要正确设置约束。标签的约束应该如下图所示

enter image description here

SurroundView的约束应如下所示。关键点是将Intrinsic Size设置为Placeholder以避免缺少约束的警告。

enter image description here



这是关键 - “通常,自动布局是从上到下执行的。换句话说,首先执行父视图布局,然后执行任何子视图布局。” - user3344977
1
我经常添加宽度约束,然后将约束从=更改为>=并分配较低的优先级。对于这个答案表示赞赏;将内在大小设置为占位符对我来说是一个启示。 - adamek

2

将标签放置在视图内,并将其顶部、底部、右侧和左侧固定到标签的父视图上。请注意,您不需要指定宽度约束。现在,向视图添加高度和宽度约束。创建一个到宽度约束的outlet,在价格更改时将视图的宽度约束常数设置为所需值。由于标签被固定在视图上,因此它也会扩展。


你好 @NavinDev,能否帮我解决这个问题:http://stackoverflow.com/questions/27103760/applying-autolayout-constraints-to-multiple-objects?谢谢。 - Ranjit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接