UILabel sizeToFit不适用于autolayout ios6

cir*_*ego 152 uilabel ios autolayout ios6

我应该如何以编程方式(以及在哪种方法中)配置UILabel,其高度取决于其文本?我一直在尝试使用Storyboard和代码的组合进行设置,但无济于事.每个人都建议sizeToFit在设置lineBreakModenumberOfLines.但是,不管我把代码viewDidLoad:,viewDidAppear:或者viewDidLayoutSubviews我不能让它开始工作.要么我的盒子太小而不能长文本也不会长,或者我把它做得太大而且不会缩小.

Mar*_*ski 405

请注意,在大多数情况下,Matt的解决方案按预期工作.但如果它不适合你,请进一步阅读.

要使标签自动调整高度,您需要执行以下操作:

  1. 设置标签的布局约束
  2. 设置低优先级的高度约束.它应该低于ContentCompressionResistancePriority
  3. 设置numberOfLines = 0
  4. 将ContentHuggingPriority设置为高于label的高度优先级
  5. 为label选择preferredMaxLayoutWidth.标签使用该值来计算其高度

例如:

self.descriptionLabel = [[UILabel alloc] init];
self.descriptionLabel.numberOfLines = 0;
self.descriptionLabel.lineBreakMode = NSLineBreakByWordWrapping;
self.descriptionLabel.preferredMaxLayoutWidth = 200;

[self.descriptionLabel setContentHuggingPriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
[self.descriptionLabel setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical];
[self.descriptionLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self addSubview:self.descriptionLabel];

NSArray* constrs = [NSLayoutConstraint constraintsWithVisualFormat:@"|-8-[descriptionLabel_]-8-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(descriptionLabel_)];
[self addConstraints:constrs];
[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-8-[descriptionLabel_]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(descriptionLabel_)]];
[self.descriptionLabel addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[descriptionLabel_(220@300)]" options:0 metrics:nil views:NSDictionaryOfVariableBindings(descriptionLabel_)]];
Run Code Online (Sandbox Code Playgroud)

使用Interface Builder

  1. 设置四个约束.高度约束是强制性的. 在此输入图像描述

  2. 然后转到标签的属性检查器并将行数设置为0. 在此输入图像描述

  3. 转到标签的大小检查器并增加垂直ContentHuggingPriority和垂直ContentCompressionResistancePriority.
    在此输入图像描述

  4. 选择并编辑高度约束.
    在此输入图像描述

  5. 并降低高度约束优先级.
    在此输入图像描述

请享用.:)

  • 你是在思考这个问题.设置`preferredMaxLayoutWidth`或固定标签的宽度(或其右侧和左侧).就这样!然后它将*自动*垂直增长和缩小以适应其内容. (43认同)
  • 是!这正是我一直在寻找的答案.我唯一需要做的就是将contentHuggingPriority和contentCompressionResistancePriority设置为必需.我可以在IB做到这一切!非常感谢. (4认同)
  • 我做了这一切,我的标签仍然被切断了. (2认同)
  • ^我终于找到了原因,可能值得一提,当你让单元格粘在视图的底部时,你需要将"到底部"约束的优先级设置为小于1000我把它放在750并且一切都很完美.我猜它缩小了观点. (2认同)

mat*_*att 65

在iOS 6中,使用自动布局,如果UILabel的边(或宽度)和顶部被固定,它将自动垂直增长和缩小以适合其内容,完全没有代码,也没有弄乱其抗压缩性等等.这很简单.

在更复杂的情况下,只需设置标签即可preferredMaxLayoutWidth.

无论哪种方式,正确的事情都会自动发生.

  • 您还需要确保将numberOfLines设置为0,否则您将无法进行换行. (11认同)
  • 这对我来说还不够。还需要@Mark的答案中的第2点。 (2认同)

Max*_*eod 42

虽然问题以编程方式陈述,遇到了同样的问题,并且更喜欢在Interface Builder中工作,但我认为使用Interface Builder解决方案添加到现有答案可能很有用.

首先要忘记sizeToFit.自动布局将根据内在内容大小代表您处理此问题.

问题是,如何通过自动布局获得标签以适应其内容?具体 - 因为问题提到它 - 身高.请注意,相同的原则适用于宽度.

让我们从高度设置为41px高的示例UILabel开始:

在此输入图像描述

正如您在上面的屏幕抓取中所看到的,"This is my text"上方和下方都有填充.这是在UILabel的高度之间的填充,它的内容是文本.

如果我们在模拟器中运行应用程序,果然,我们看到同样的事情:

在此输入图像描述

现在,让我们在Interface Builder中选择UILabel,然后查看Size检查器中的默认设置:

在此输入图像描述

注意上面突出显示的约束.这就是内容拥抱优先级.正如Erica Sadun在优秀的iOS Auto Layout Demystified中描述的那样,这是:

视图更喜欢避免在其核心内容周围添加额外填充的方式

对我们来说,使用UILabel,核心内容就是文本.

在这里,我们来到这个基本场景的核心.我们给了我们的文本标签两个约束.他们发生冲突 一个人说"高度必须等于41像素高".另一个说"拥抱它的内容,所以我们没有任何额外的填充".在我们的例子中,拥抱视图的文本,所以我们没有任何额外的填充.

现在,使用自动布局,有两个不同的指令,表示做不同的事情,运行时必须选择其中一个.它不能两者兼顾.UILabel不能同时为41像素高,并且没有填充.

解决这个问题的方法是指定优先级.一条指令必须具有比另一条指令更高的优先级.如果两个指令都说不同,并具有相同的优先级,则会发生异常.

让我们试一试.我的身高限制优先级为1000,这是必需的.内容拥抱高度为250,这是弱的.如果我们将高度约束优先级降低到249会发生什么?

在此输入图像描述

现在我们可以看到神奇的开始发生.我们来试试吧:

在此输入图像描述

真棒!内容拥抱实现.仅因为高度优先级249小于内容拥抱优先级250.基本上,我说"我在这里指定的高度不如我为内容拥抱指定的那么重要".所以,内容拥抱获胜.

底线,使标签适合文本可以像指定高度 - 或宽度 - 约束一样简单,并正确设置与该轴的内容拥抱优先级约束相关的优先级.

对于读者而言,将为宽度做一个相当于练习的练习!

  • 非常感谢您的精彩解释!最后,我理解内容拥抱优先级. (3认同)
  • Excelente回答Max!是否有某种方式可以限制以这种方式工作的行数? (2认同)

小智 7

在IOS7中注意到sizeToFit也不起作用 - 也许解决方案也可能对你有所帮助

[textView sizeToFit];
[textView layoutIfNeeded];
Run Code Online (Sandbox Code Playgroud)