Избегайте одиночных символов в многострочном UILabel для новой строки - PullRequest
0 голосов
/ 18 июня 2019

У меня есть UILabel (динамического размера) с numberOfLines = 2.

В зависимости от текста, поступающего из BE, текст переносится красиво или нет.

У кого-нибудь есть какие-либо советы покак запретить разделять (длинные) слова в 2 строки и иметь только один символ в новой строке?

Текущее поведение:

Thisisalongwor
d

Требуемое поведение:

Thisisalong
word

В основном: я хотел бы установить минимальное количество символов в строке (при переносе элементов с первой строки на вторую).

Спасибо!

1 Ответ

1 голос
/ 18 июня 2019

Вот один подход ...

Используйте функции CoreText, чтобы получить массив обернутых строк из метки. Если последняя строка имеет не менее 1 символа, но меньше 4 символов, а полный текст больше 4 символов, вставьте 4 символа перевода строки в конце текста и обновите метку.

Итак, на основе стандартного UILabel - 17-pt системного шрифта - с фиксированной шириной 123-pts и обтеканием, установленным на Character Wrap, это выглядит так:

enter image description here

После запуска функции fixLabelWrap(...) это выглядит так:

enter image description here

Пример кода:

class CharWrapViewController: UIViewController {

    @IBOutlet var theLabel: UILabel!

    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        fixLabelWrap(theLabel)
    }

    func fixLabelWrap(_ label: UILabel) -> Void {

        // get the text from the label
        var text = theLabel.text ?? ""

        // get an array of the char-wrapped text
        let lines = getLinesArrayOfString(in: theLabel)

        // if it is more than one line
        if lines.count > 1 {
            // get the last line
            if let lastLine = lines.last {
                // if the last line has at least 1 char, is less than 4 chars, and
                // the full text is greater than 4 chars
                if lastLine.count > 0 && lastLine.count < 4 && text.count > 4 {
                    // insert a line-feed 4 chars before the end
                    text.insert("\n", at: text.index(text.endIndex, offsetBy: -4))
                    // update the text in the label
                    theLabel.text = text
                }
            }
        }

    }

    func getLinesArrayOfString(in label: UILabel) -> [String] {

        /// An empty string's array
        var linesArray = [String]()

        guard let text = label.text, let attStr = label.attributedText else { return linesArray }

        let rect = label.frame

        let frameSetter: CTFramesetter = CTFramesetterCreateWithAttributedString(attStr as CFAttributedString)
        let path: CGMutablePath = CGMutablePath()
        path.addRect(CGRect(x: 0, y: 0, width: rect.size.width, height: 100000), transform: .identity)

        let frame: CTFrame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(0, 0), path, nil)
        guard let lines = CTFrameGetLines(frame) as? [Any] else {return linesArray}

        for line in lines {
            let lineRef = line as! CTLine
            let lineRange: CFRange = CTLineGetStringRange(lineRef)
            let range = NSRange(location: lineRange.location, length: lineRange.length)
            let lineString: String = (text as NSString).substring(with: range)
            linesArray.append(lineString)
        }

        return linesArray
    }

}

Примечание: функция getLinesArrayOfString(...) является слегка измененной версией сообщения, найденного здесь: https://stackoverflow.com/a/14413484/6257435

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...