简体   繁体   English

自动换行在UILabel中不起作用

[英]Word wrap not working in UILabel

Below result, for UILabel . 在结果下方,用于UILabel it only happens if the word is too long. 仅当单词太长时才会发生。

在此处输入图片说明

Below is something I want to achieve. 以下是我要实现的目标。 It works if I reduce the Lable height. 如果我降低标签高度,它会起作用。 but Label height is dynamic 但是标签高度是动态的

在此处输入图片说明

Help appreciate. 帮助欣赏。 Thank you 谢谢

As I found out all lineBreakMode modes will pass characters on another line when the word is bigger than that line. 我发现,当单词比该行大时,所有lineBreakMode模式都会在另一行传递字符。 It seems that the only way to fix it is to change font size to fit this word. 似乎解决此问题的唯一方法是更改​​字体大小以适合该单词。 Autoshrink has some limitations and does not detect splitting word to several lines, so you need manually detect that word is not fitted and change font size accordingly. 自动收缩功能有一些局限性,不能检测将单词拆分为多行,因此您需要手动检测到单词不适合,并相应地更改字体大小。

Question with the same problem: How to make multi-line UILabel text fit within predefined width without wrapping mid-word 相同问题的问题: 如何使多行UILabel文本适合预定义的宽度而又不包装中间单词

You can set constraint as your requirement for a label. 您可以将约束设置为标签要求。 suppose if you don't want fix height then It's not necessary to set bottom constraint. 假设如果您不希望固定高度,则无需设置底部约束。

See below image I have set a constraint for dynamic label height. 参见下图,我为动态标签高度设置了一个约束。 Hope this will help you. 希望这会帮助你。

约束 属性

Try this. 尝试这个。 It should shrink the font just enough to fit the longest word on a line. 它应该将字体缩小到恰好适合一行中最长的单词。 If you see a better way let me know as I would love to improve this.I am sure I could adapt it to work in IB. 如果您认为有更好的方法,请告诉我,我很乐意对此进行改进。我相信我可以将其改编为在IB工作。

import UIKit

extension UILabel{

    func adjustedFont()->UIFont {
        let attributes: [NSAttributedStringKey: Any] = [.font: font]
        let attributedString = NSAttributedString(string: text ?? "", attributes: attributes)
        let drawingContext = NSStringDrawingContext()
        drawingContext.minimumScaleFactor = minimumScaleFactor

        attributedString.boundingRect(with: bounds.integral.size,
                                      options: .usesLineFragmentOrigin,
                                      context: drawingContext)

        let fontSize = font.pointSize * drawingContext.actualScaleFactor

        return font.withSize(fontSize)
    }

    func fitMaxWord(){
        layoutIfNeeded()
        let scaledFont = self.adjustedFont()
        let currentFont = scaledFont
        if let txt = text,
            let maxString = txt.components(separatedBy: " ").max(by: {$1.count > $0.count})?.replacingOccurrences(of: "\n", with: ""){
            let maxFontSize: CGFloat = currentFont.pointSize
            let minFontSize: CGFloat = 5.0


            var q = maxFontSize
            var p = minFontSize
            let height = currentFont.lineHeight
            let constraintSize = CGSize(width: .greatestFiniteMagnitude, height: height)
            var sizedFont = currentFont
            while(p <= q){
                let currentSize = (p + q) / CGFloat(2)
                sizedFont = currentFont.withSize( CGFloat(currentSize) )

                let text = NSMutableAttributedString(string:maxString, attributes:[NSAttributedStringKey.font:sizedFont])

                let textRect = text.boundingRect(with: constraintSize, options: [.usesLineFragmentOrigin], context: nil).integral
                let labelSize = textRect.width

                //1 is a fudge factor
                if labelSize == ceil(self.bounds.width - 1){
                    break
                }else if labelSize > ceil(self.bounds.width - 1){
                    q = currentSize - 0.1
                }else{
                    p = currentSize + 0.1
                }
            }

            if sizedFont.pointSize < currentFont.pointSize{
                self.font = sizedFont
            }
        }
    }
}

Minimum example: 最小示例:

import UIKit 导入UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        //we could test longer text
        //
        let text = "CHULALONGKORN UNIVERSITY Plus a lot of additional text to make sure it still does not clip a word"
        let testLabel = UILabel(frame: .zero)
        //testLabel.text = "CHULALONGKORN UNIVERSITY"
        testLabel.text = text
        testLabel.numberOfLines = 0
        testLabel.textAlignment = .center
        testLabel.font = UIFont.systemFont(ofSize: 45)
        testLabel.adjustsFontSizeToFitWidth = true //unneeded in this instance but lets set it
        testLabel.minimumScaleFactor = 0.3
        self.view.addSubview(testLabel)
        testLabel.translatesAutoresizingMaskIntoConstraints = false
        testLabel.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 20).isActive = true
        testLabel.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -20).isActive = true
        testLabel.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 50).isActive = true
        self.view.layoutIfNeeded()
        testLabel.fitMaxWord()
    }


}

ExampleImage This should work in most circumstances. 这在大多数情况下都应该起作用。 I tested with your text and more text. 我测试了您的文字和更多文字。 You can see both in the example above. 您可以在上面的示例中看到两者。

Here is a solution to your problem if, your string has fixed value, as you've shown in your question (ie CHULALONGKORN UNIVERSITY ). 如果您的字符串具有固定值(如您在问题中所显示的那样,即CHULALONGKORN UNIVERSITY ),这是解决您问题的方法。

Set following properties for your label in your interface builder. 在界面构建器中为标签设置以下属性。

  1. Set your label text value in two lines, as shown in below snapshot (not in a single line like - CHULALONGKORN UNIVERSITY ). 如以下快照所示,在两行中设置标签文本值(而不是像CHULALONGKORN UNIVERSITY这样的CHULALONGKORN UNIVERSITY )。 Press alt + enter inplace of space between two words. alt +输入两个单词之间的空格。
  2. Set number of lines = 2 设置行数= 2
  3. Set line break mode = Truncate Tail 设置换行模式=截尾
  4. Set Autoshrink to Minimum Font Scale' and value for scale to 0.5` or whatever minimum scale you like to set. 将“自动收缩Minimum Font Scale' and value for scale to设置为“ Minimum Font Scale' and value for scale to 0.5`或您要设置的任何最小比例。

- -- 在此处输入图片说明

you should try UILabel alignment justified 你应该尝试UILabel对齐 在此处输入图片说明

whenever you give label height as Dynamic 每当您将标签高度设为动态时

Select the Lines Count as 0 in Attributes Inspector 在“属性”检查器中将“ 数”选择为0 在此处输入图片说明

Then automatically based on the Content of label the height is increases. 然后根据标签的内容自动增加高度。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM