iOS Autolayout:调整大小父视图中的 UILabels 问题 [英] iOS Autolayout: Issue with UILabels in a resizing parent view

查看:19
本文介绍了iOS Autolayout:调整大小父视图中的 UILabels 问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个只包含 UILabel 的视图.此标签包含多行文本.父级具有可变宽度,可以使用平移手势调整大小.我的问题是,当我调整 UILabel 的大小时,它不会重新计算其高度以使所有内容仍然可见,它只是将其切断.

I've got a view that contains only a UILabel. This label contains multiline text. The parent has a variable width that can be resized with a pan gesture. My problem is that when I do this resizing the UILabel does not recalculate its height such that all of the content is still visible, it simply cuts it off.

我已经设法通过一些 hack 来修复它,但运行起来非常慢:

I've managed to fix it with a bit of a hack but it is horribly slow to run:

- (void)layoutSubviews {

    CGSize labelSize = [self.labelDescription sizeThatFits:CGSizeMake(self.frame.size.width, FLT_MAX)];

    if (self.constraintHeight) {
        [self removeConstraint:self.constraintHeight];
    }

    self.constraintHeight = [NSLayoutConstraint constraintWithItem:self.labelDescription attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:labelSize.height];

    [self addConstraint:self.constraintHeight];

    [super layoutSubviews];
}

这不应该通过自动布局自动发生吗?

Shouldn't this happen automatically with autolayout?

编辑

我的视图结构是:

UIScrollView
---> UIView
     ---> UILabel

以下是 UIScrollView 的约束:

Here are the constraints on the UIScrollView:

<NSLayoutConstraint:0x120c4860 H:|-(>=32)-[DescriptionView:0x85c81c0]   (Names: '|':UIScrollView:0x85db650 )>,
<NSLayoutConstraint:0x120c48a0 H:|-(32@900)-[DescriptionView:0x85c81c0] priority:900   (Names: '|':UIScrollView:0x85db650 )>,
<NSLayoutConstraint:0x120c48e0 H:[DescriptionView:0x85c81c0(<=576)]>,
<NSLayoutConstraint:0x120c4920 H:[DescriptionView:0x85c81c0]-(>=32)-|   (Names: '|':UIScrollView:0x85db650 )>,
<NSLayoutConstraint:0x120c4960 H:[DescriptionView:0x85c81c0]-(32@900)-| priority:900   (Names: '|':UIScrollView:0x85db650 )>,
<NSLayoutConstraint:0x8301450 DescriptionView:0x85c81c0.centerX == UIScrollView:0x85db650.centerX>,

以下是对 UIView 的约束:

Here are the constraints on the UIView:

<NSLayoutConstraint:0x85c4580 V:|-(0)-[UILabel:0x85bc7b0]   (Names: '|':DescriptionView:0x85c81c0 )>,
<NSLayoutConstraint:0x85c45c0 H:|-(0)-[UILabel:0x85bc7b0]   (Names: '|':DescriptionView:0x85c81c0 )>,
<NSLayoutConstraint:0x85c9f80 UILabel:0x85bc7b0.trailing == DescriptionView:0x85c81c0.trailing>,
<NSLayoutConstraint:0x85c9fc0 UILabel:0x85bc7b0.centerY == DescriptionView:0x85c81c0.centerY>

UILabel 本身对它没有任何限制,除了将其固定到其父对象的边缘

The UILabel itself has no constraints on it, aside from pinning it to the edges of its parent

推荐答案

在向 Apple 提出错误后,我已修复此问题.多行文本需要两次布局的问题,这一切都依赖于属性 preferredMaxLayoutWidth

I've fixed this issue after raising a bug with Apple. The issue that multiline text requires a two-pass approach to layout and it all relies on the property preferredMaxLayoutWidth

以下是需要添加到包含多行标签的视图控制器的相关代码:

Here is the relevant code that needs to be added to a view controller that contains a multiline label:

- (void)viewWillLayoutSubviews
{
    // Clear the preferred max layout width in case the text of the label is a single line taking less width than what would be taken from the constraints of the left and right edges to the label's superview
    [self.label setPreferredMaxLayoutWidth:0.];
}

- (void)viewDidLayoutSubviews
{
    // Now that you know what the constraints gave you for the label's width, use that for the preferredMaxLayoutWidth—so you get the correct height for the layout
    [self.label setPreferredMaxLayoutWidth:[self.label bounds].size.width];

    // And then layout again with the label's correct height.
    [self.view layoutSubviews];
}

这篇关于iOS Autolayout:调整大小父视图中的 UILabels 问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆