iOS UILabel Core Текст количество строк - PullRequest
0 голосов
/ 25 февраля 2020

Я хочу создать пользовательский подкласс UILabel, который будет знать текущее количество отображаемых строк. Как я понял, UILabel автоматически меняет свое свойство attributedText при изменении text или font. Поэтому я пытаюсь сделать что-то подобное:

label.text = "some very long text"
label.font = .systemFont(ofSize: 12)

guard let attrStr = label.attributedText else {
    return
}

print(attrStr.lines(fittingWidth: 600).count)

...

extension NSAttributedString {
    func lines(fittingWidth width: CGFloat) -> [String] {
        let attributedString = self
        let framesetter =
            CTFramesetterCreateWithAttributedString(
                attributedString
            )
        let path = CGPath(rect: CGRect(
            x: 0,
            y: 0,
            width: width,
            height: .greatestFiniteMagnitude
        ), transform: nil)
        let frame = CTFramesetterCreateFrame(
            framesetter,
            CFRange(location: 0, length: 0),
            path,
            nil
        )
        let lines = CTFrameGetLines(frame) as! [CTLine]

        var strLines = [String]()
        let nsString = attributedString.string as NSString
        for line in lines {
            let lineRange = CTLineGetStringRange(line)
            let range = NSMakeRange(lineRange.location, lineRange.length)
            strLines.append(nsString.substring(with: range))
        }
        return strLines
    }
}

Но проблема в том, что lines(fittingWidth:) всегда возвращает только 1 строку для любой ширины подгонки, когда я использую значение attributedText метки. В то же время, когда я сам создаю NSAttributedString (используя свойства text и font), lines(fittingWidth:) возвращает правильное количество строк. Что не так со встроенным значением attributedText?

...