当字体大小大于标签高度时,防止 UILabel 剪切其文本

问题描述 投票:0回答:4

我的应用程序中有一种情况,标签的字体大小可能大于其高度。这与一些相当复杂的架构和布局代码有关。通常我会增加标签的高度以适应更大的字体,但这在我的场景中很难做到,我宁愿避免它。

下一个合乎逻辑的事情是关闭

clipsToBounds
,以允许文本子层溢出标签的边界。不幸的是,这在这种情况下似乎没有效果,因为文本仍然被剪裁。

我错过了什么吗?

ios swift uilabel clipping
4个回答
1
投票

查看 UILabel 的文档:

https://developer.apple.com/documentation/uikit/uilabel/1620545-textrect

我认为您需要重写方法 textRect(forBounds:limitedToNumberOfLines:) 通过显式增加此方法返回的矩形到标签字符串的包含大小而不是标签的边界。

(这个解决方案当然需要您子类化。)

希望有帮助。


0
投票

您应该能够从

font.lineHeight
获取字体高度,然后减小字体大小,直到行高小于标签高度。


0
投票

原因(需要引用)是嵌入在 UIButton 中的 UILabel 关心嵌入在字体中的额外字形信息,而独立的 UILabel 则不关心。

解决方案

您可以在 UIButton 之上嵌套一个单独的 UILabel ,它将解决问题。它很丑,但很有效。您应该尝试一些解决方法。

解决方法

根据具体情况,这里有一个小清单,我发现它是可接受的答案或对某人有用。

1)如果您使用的是 UIButton 请确保您使用的是此方法

[button setTitle forState:]

否则你需要使用以下代码来刷新状态

[myButton setNeedsLayout];

2) 您可能需要调整字体大小以适合标签的宽度。

[yourLabel setAdjustsFontSizeToFitWidth:YES];

3)虽然设置clipToBounds可以在连续的层次结构中工作,但您可能不想在Button或Label上单独设置。

[yourButton setClipsToBounds:NO];
[yourButton.titleLabel setClipToBounds:NO];

很少有解决方案指向 UIButton 子类化方法,这些方法本质上是试图将 UIEdgeInset 添加到按钮。


0
投票

当我在 TableView 单元格内对

UILabel
的高度变化进行动画处理时,我遇到了类似的情况。随着标签尺寸的增大,标签文本的顶部被剪裁。我知道您无法根据您的情况对标签进行子类化,但发布我的解决方案以防对其他人有帮助。

我使用了

UILabel
的子类,它向标签的内容添加了一个插图。还使用我将提供的
UIEdgeInset
扩展:

class InsetLabel: UILabel {
    var inset = UIEdgeInsets.zero {
        didSet {
            self.invalidateIntrinsicContentSize()
        }
    }

    override func drawText(in rect: CGRect) {
        super.drawText(in: rect.inset(by: self.inset))
    }

    override open func layoutSubviews() {
        super.layoutSubviews()
        self.preferredMaxLayoutWidth = self.frame.width - self.inset.width
    }

    override var intrinsicContentSize: CGSize {
        let superSize = super.intrinsicContentSize
        let width = superSize.width + self.inset.width
        let height = superSize.height + self.inset.height
        return CGSize(width: width, height: height)
    }
}
extension UIEdgeInsets {
    init(top: CGFloat = 0, left: CGFloat = 0, bottom: CGFloat = 0, right: CGFloat = 0) {
        self.init()
        self.top = top
        self.left = left
        self.right = right
        self.bottom = bottom
    }

    init(value: CGFloat) {
        self.init()
        self.top = value
        self.right = value
        self.bottom = value
        self.left = value
    }

    var width: CGFloat { self.left + self.right }
    var height: CGFloat { self.top + self.bottom }
}
© www.soinside.com 2019 - 2024. All rights reserved.