如何限制Swift中String或属性String中的字符数

时间:2017-04-12 20:52:27

标签: swift string

给定是一个带有x个字符的(html)字符串。 String将被格式化为属性String。然后显示在UILabel

UILabel的高度为>= 25<= 50,以将行数限制为2.

由于String具有在格式化的属性String中不可见的字符,如<b> / <i>,因此最好的方法是限制属性String的字符数。

UILabel属性.lineBreakMode = .byTruncatingTail导致单词被删除。

enter image description here

目标,如果字符数超过UILabel中的空间限制,则在字词之间剪切。期望的maxCharacterCount = 50。确定space之前的最后maxCharacterCount。剪切字符串并将...附加为UILabel的最后一个字符。

限制角色的最佳方法是什么?帮助非常感谢。

4 个答案:

答案 0 :(得分:11)

从标签的完整字符串和已知的双线高度及其已知宽度开始,并保持字符串末端的切词,直到在该宽度处,字符串的高度小于标签的高度。然后在末尾再剪一个单词以获得良好的度量,附加省略号,并将得到的字符串放入标签中。

通过这种方式,我得到了这个:

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
        }
    }

当然可能很多更复杂的关于什么构成“单词”和测量条件,但上面演示了这种事情的一般常用技术,应该足够让你入门。

答案 1 :(得分:5)

试试这个:

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.
}


}

string width calculation link

答案 2 :(得分:2)

仅记录Matt's answer是正确的,但您可以通过创建自己的UILabel子类来删除任何可能的问题,该子类将原始值存储在变量中。比方向更改时,您可以从视图控制器更新其布局。

答案 3 :(得分:0)

快速纠正Mikael Weiss的答案。

if str.count > thisInt +3{
    while str.count >= thisInt {
        str.remove(at: str.index(before: str.endIndex))
    }
    str.append("...")
}