Как ограничить количество символов в строке или приписываемой строке в Swift

задана строка (html) с x-числом символов. Строка будет отформатирована в строку attributed. Затем отображается в UILabel.

на UILabel высота >= 25 и <= 50 чтобы ограничить количество строк до 2.

поскольку строка имеет символы, не видимые в отформатированной атрибутивной строке, например <b> / <i>, лучшим подходом было бы ограничить количество символов приписываемой строки.

UILabel собственность .lineBreakMode = .byTruncatingTail заставляет слова сокращаться.

enter image description here

цель в случае, если количество символов будет превышать лимит пространства UILabel, Это вырезать между словами. Желаемое maxCharacterCount = 50. Определите последнее space до maxCharacterCount. Вырезать строку и добавить ... как последние символы UILabel.

каков наилучший подход к ограничению символов? Помощь очень ценю.

3 ответов


начните с полной строки и известной двухстрочной высоты метки и ее известной ширины и продолжайте отрезать слова от конца строки, пока на этой ширине высота строки не будет меньше высоты метки. Затем отрежьте еще одно слово от конца для хорошей меры, добавьте многоточие и поместите полученную строку в метку.

таким образом, я получил это:

enter image description here

обратите внимание, что слово после "Время" никогда не начинается; мы остановитесь на точном слове-конце со вставленным многоточием. Вот как я это сделал:

    lab.numberOfLines = 2
    let s = "Little poltergeists make up the principle form of material " +
        "manifestation. Now is the time for all good men to come to the " +
        "aid of the country."
    let atts = [NSFontAttributeName: UIFont(name: "Georgia", size: 18)!]
    let arr = s.components(separatedBy: " ")
    for max in (1..<arr.count).reversed() {
        let s = arr[0..<max].joined(separator: " ")
        let attrib = NSMutableAttributedString(string: s, attributes: atts)
        let height = attrib.boundingRect(with: CGSize(width:lab.bounds.width, 
                                                      height:10000),
                                         options: [.usesLineFragmentOrigin],
                                         context: nil).height
        if height < lab.bounds.height {
            let s = arr[0..<max-1].joined(separator: " ") + "…"
            let attrib = NSMutableAttributedString(string: s, attributes: atts)
            lab.attributedText = attrib
            break
        }
    }

конечно, можно быть много более сложные о том, что составляет "Слово" и в условиях измерения, но выше демонстрирует общую общую технику для такого рода вещей и должно быть достаточно, чтобы начать.


попробуйте это:

import UIKit

class ViewController: UIViewController {
var str = "Hello, playground"
var thisInt = 10
@IBOutlet weak var lbl: UILabel!
var lblWidth : CGFloat = 0.0

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    lblWidth = lbl.bounds.width

    while str.characters.count <= thisInt - 3 {
        str.remove(at: str.index(before: str.endIndex))
        str.append("...")
    }
    lbl.text = str
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}

строка ширина расчет ссылка


просто для протокола ответ Мэтта правильно, но вы можете удалить любые возможные проблемы, создав свой собственный подкласс UILabel, который будет хранить исходное значение в переменной. Чем вы можете обновить его макет из контроллера вида, когда ориентация была изменена.