UILabel sizeToFit不';无法使用自动布局ios6

UILabel sizeToFit不';无法使用自动布局ios6,ios,ios6,uilabel,autolayout,Ios,Ios6,Uilabel,Autolayout,我应该如何以编程方式(以及以何种方法)配置高度取决于文本的UILabel?我一直在尝试使用故事板和代码的组合进行设置,但没有效果。在设置lineBreakMode和numberOfLines时,每个人都推荐sizeToFit。但是,无论我将该代码放入viewDidLoad:,viewdide:,或viewDidLayoutSubviews中,我都无法让它工作。要么我将框设置得太小,无法容纳长文本,要么我将框设置得太大,无法缩小。请注意,在大多数情况下,效果与预期一致。但如果它不适合你,请进一步阅

我应该如何以编程方式(以及以何种方法)配置高度取决于文本的UILabel?我一直在尝试使用故事板和代码的组合进行设置,但没有效果。在设置
lineBreakMode
numberOfLines
时,每个人都推荐
sizeToFit
。但是,无论我将该代码放入
viewDidLoad:
viewdide:
,或
viewDidLayoutSubviews
中,我都无法让它工作。要么我将框设置得太小,无法容纳长文本,要么我将框设置得太大,无法缩小。

请注意,在大多数情况下,效果与预期一致。但如果它不适合你,请进一步阅读

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

  • 设置标签的布局约束
  • 设置低优先级的高度约束。它应低于内容压缩阻力优先级
  • 设置numberOfLines=0
  • 将ContentHuggingPriority设置为高于标签的高度优先级
  • 为标签设置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_)]];
    
    使用界面生成器

  • 设置四个约束。高度约束是强制性的。

  • 然后转到标签的属性检查器,并将行数设置为0。

  • 转到标签的大小检查器,增加垂直内容HuggingPriority和垂直内容CompressionResistancePriority。

  • 选择并编辑高度约束。

  • 并降低高度约束优先级。


  • 享受。:)

    在iOS 6中,使用自动布局,如果UILabel的侧面(或宽度)和顶部被钉住,它将自动垂直增长和收缩以适应其内容,完全没有代码,也不会影响其抗压性或其他性能。这非常简单

    在更复杂的情况下,只需设置标签的
    首选MaxLayoutWidth


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

    在IOS7中注意到sizeToFit也不起作用-也许该解决方案也会对您有所帮助

    [textView sizeToFit];
    [textView layoutIfNeeded];
    

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

    第一件事是忘记
    sizeToFit
    。自动布局将根据内部内容大小代表您处理此问题

    因此,问题是,如何通过自动布局获得适合其内容的标签?特别是——因为问题提到了——高度。请注意,相同的原则适用于宽度

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

    正如您在上面的屏幕抓图中所看到的,
    “这是我的文本”
    上下都有填充。这是UILabel高度和内容文本之间的填充

    如果我们在模拟器中运行应用程序,肯定会看到同样的情况:

    现在,让我们在Interface Builder中选择UILabel,并查看尺寸检查器中的默认设置:

    请注意上面突出显示的约束。这就是内容优先权。正如Erica Sadun在《卓越》中所描述的,这是:

    视图倾向于避免在其核心内容周围添加额外的填充

    对于我们来说,UILabel的核心内容是文本

    在这里,我们来到这个基本场景的核心。我们给了文本标签两个约束条件。它们相互冲突。有人说“高度必须等于41像素高”。另一个说“拥抱视图的内容,这样我们就不会有任何额外的填充”。在我们的例子中,将视图放在文本中,这样我们就不会有任何额外的填充

    现在,使用Auto Layout,使用两个不同的指令执行不同的操作,运行时必须选择其中一个。不能两者兼而有之。UILabel不能既有41像素高,又没有填充

    解决此问题的方法是指定优先级。一条指令的优先级必须高于另一条指令。如果两条指令所说的内容不同,并且具有相同的优先级,则会发生异常

    所以,让我们试一试。“我的高度”约束的优先级为1000,这是必需的。内容拥抱高度为250,即。如果我们将高度约束优先级降低到249,会发生什么情况

    现在我们可以看到奇迹开始发生了。让我们在sim卡中试试:

    太棒了!实现了内容拥抱。只是因为高度优先权249小于内容优先权250。基本上,我是说“我在这里指定的高度没有我为内容拥抱指定的高度重要”。因此,内容拥抱获胜

    底线是,让标签适合文本可以很简单,只需指定高度或宽度约束,并将该优先级与轴的内容包含优先级约束相关联进行正确设置。


    对于读者来说,做宽度的等效操作是一个练习

    在我的例子中,我创建了一个包含UILabel(长度未知)的UIView子类。在iOS7中,代码很简单:设置约束,不必担心内容占用或压缩阻力,一切都按预期进行

    但在iOS6中,UILabel总是被剪裁成一行。上面的答案都不适合我。内容拥抱和压缩阻力设置被忽略。阻止剪切的唯一解决方案是在标签上包含preferredMaxLayoutWidth。但我不知道该将首选宽度设置为什么,因为其父视图的大小未知(I
    [textView sizeToFit];
    [textView layoutIfNeeded];
    
    - (void)layoutSubviews
    {
        // Autolayout hack required for iOS6
        [super layoutSubviews];
        self.bodyLabel.preferredMaxLayoutWidth = self.bodyLabel.frame.size.width;
        [super layoutSubviews];
    }
    
    #import "MyLabel.h"
    
    @implementation MyLabel
    
    -(void)setBounds:(CGRect)bounds
    {
        [super setBounds:bounds];
    
        // This appears to be needed for iOS 6 which doesn't seem to keep
        // label preferredMaxLayoutWidth in sync with its width, which 
        // means the label won't grow vertically to encompass its text if 
        // the label's width constraint changes.
        self.preferredMaxLayoutWidth = self.bounds.size.width;
    }
    
    @end
    
    self.tableView.rowHeight = UITableViewAutomaticDimension.  
    
    - (CGSize)intrinsicContentSize
    {
        CGRect expectedTextBounds = [self.titleLabel textRectForBounds:self.titleLabel.bounds limitedToNumberOfLines:1];
        self.titleLabelHeightConstraint.constant = expectedTextBounds.size.height;
        return [self.containerView intrinsicContentSize];
    
    }
    
    label.translatesAutoresizingMaskIntoConstraints = false
    label.setContentCompressionResistancePriority(UILayoutPriorityRequired, forAxis: .Vertical)
    label.numberOfLines = 0