如何在具有无限行的UILabel上自动换行?

时间:2018-07-20 06:11:41

标签: ios swift uilabel

我有一个UILabel,其中行数需要设置为0(无限行)。但是,当它显示单个长字时,它会按字符将行换行,以形成第二行。我试图这样手动设置换行模式

cell.nameLbl.adjustsFontSizeToFitWidth = true
cell.nameLbl.lineBreakMode = .byWordWrapping

但是该应用仍然会按字符中断。我怎样才能解决这个问题? 编辑-我希望缩小字型。

1 个答案:

答案 0 :(得分:0)

不幸的是,调整字体大小是针对每个标签而不是每一行。包装不会影响它。因此,您所看到的结果是预期的。您可以将字符串手动拆分为多个标签,也可以将它们放入堆栈视图中以获得所需的结果。

我尝试过的是:

private func layoutText(text: String, onStackView stackView: UIStackView) {
    var words: [String] = text.components(separatedBy: .whitespaces)

    var currentLineWords: [String] = [String]()
    var currentLabel: UILabel!

    func newLabel() -> UILabel {
        let label = UILabel(frame: stackView.bounds)
        label.adjustsFontSizeToFitWidth = true
        label.minimumScaleFactor = 0.5
        return label
    }

    while words.count > 0 {
        if currentLineWords.count == 0 {
            currentLabel = newLabel()
            currentLineWords.append(words.removeFirst())
        } else {
            let newText = currentLineWords.joined(separator: " ") + " " + words[0]
            currentLabel.text = newText
            currentLabel.sizeToFit()

            if currentLabel.bounds.width > stackView.bounds.width {
                // Break line
                currentLabel.text = currentLineWords.joined(separator: " ")
                stackView.addArrangedSubview(currentLabel)
                currentLabel = nil
                currentLineWords = [String]()
            } else {
                // All good
                currentLineWords.append(words.removeFirst())
            }
        }
    }

    if currentLineWords.count > 0 {
        currentLabel.text = currentLineWords.joined(separator: " ")
        stackView.addArrangedSubview(currentLabel)
    }
}

这很好用,但是:

  • 当单词太长而不能缩成一行时,它的末尾也会显示“ ...”
  • 收缩线仍具有相同的高度,而不是减小高度
  • 我们只处理空格并插入退格符

使用手册adjustsFontSizeToFitWidth可能会解决前两个问题。基本上一直减小字体大小,直到适合为止或达到一定大小为止。如果遇到“一定大小”的情况,则只需在标签上使用多行(将按字符分隔)。

最后一个需要付出额外的努力。

出于多种原因,我仍然不会实施此操作,其中一个原因是它看上去很丑,但仍然很有趣。

自定义字体大小调整:

要进行自定义字体调整和所有逻辑,只有在创建新的留置权后才需要更改:

            if currentLineWords.count == 0 {
                currentLabel = newLabel()
                currentLineWords.append(words.removeFirst())

                currentLabel.text = currentLineWords.joined(separator: " ")
                currentLabel.sizeToFit()

                if currentLabel.bounds.width > stackView.bounds.width {
                    currentLabel.adjustsFontSizeToFitWidth = false

                    let originalFontSize: CGFloat = currentLabel.font.pointSize
                    var currentFontSize: CGFloat = originalFontSize
                    let minimalFontSize: CGFloat = currentLabel.minimumScaleFactor > 0.0 ? currentLabel.font.pointSize * currentLabel.minimumScaleFactor : originalFontSize

                    while currentLabel.bounds.width > stackView.bounds.width {
                        currentFontSize -= 1.0
                        if currentFontSize < minimalFontSize {
                            currentLabel.numberOfLines = 0
                            currentLabel.font = UIFont(name: currentLabel.font.fontName, size: originalFontSize)
                            break // Could not shrink it even further. USe multiline
                        }
                        currentLabel.font = UIFont(name: currentLabel.font.fontName, size: currentFontSize)
                        currentLabel.sizeToFit()
                    }

                    // Break line
                    stackView.addArrangedSubview(currentLabel)
                    currentLabel = nil
                    currentLineWords = [String]()
                }
            } 

这看起来现在可用。我的结果:

enter image description here