- 变态需求要根据屏幕宽度,first name长度不确定
- first name较短
- 若 Good morning, first name,1行能显示下, 用 Good morning, first name
- 若 Good morning, first name,1行不能显示下:若Hi, first name 能显示下,则用Hi否则考虑两行的情况。
两行情况同上,但是换行的时候得在第一行的末尾加 -
- first name特别长
- 用Hi,且末尾得加上 ...
- 先上代码吧
// 1.初始化路径
let path = CGPath(rect: self.bounds, transform: nil)
// 2.初始化framesetter
let framesetter = CTFramesetterCreateWithAttributedString(text)
// 3.绘制frame
let frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, text.length), path, nil)
self.ctframe = frame
// 获得CTLine数组
let lines = CTFrameGetLines(frame)
// 获得行数
let numberOfLines = CFArrayGetCount(lines)
// 获得每一行的origin, CoreText的origin是在字形的baseLine处的
var lineOrigins = [CGPoint](repeating: CGPoint(x: 0, y: 0), count: numberOfLines)
CTFrameGetLineOrigins(frame, CFRangeMake(0, 0), &lineOrigins)
// 遍历每一行
for index in 0..<numberOfLines {
let origin = lineOrigins[index]
let line = unsafeBitCast(CFArrayGetValueAtIndex(lines, index), to: CTLine.self)
let lineRef: CTLine = line
let lineRange: CFRange = CTLineGetStringRange(lineRef)
let range: NSRange = NSMakeRange(lineRange.location, lineRange.length)
let lineString = (attributedText?.attributedSubstring(from: range)).string
}
这样就得到了每一行的characters
重要的是这个是利用CoreText 的富文本属性去做的,一定要是这个Label的NSMutableAttributedString, 然后把得到的string转成 AttributedString,给label的富文本属性,这样才正确。
- 富文本属性简单用法举例:
let font = UIFont.boldSystemFont(ofSize: 20)
let attributedText = NSMutableAttributedString(string: content)
// 字体颜色
attributedText.addAttribute(NSForegroundColorAttributeName, value: UIColor.red, range: NSMakeRange(0, attributedText.length))
// 字体
attributedText.addAttribute(NSFontAttributeName, value: font, range: NSMakeRange(0, attributedText.length))
// 段落样式
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
paragraphStyle.lineBreakMode = .byCharWrapping
// 行间距
paragraphStyle.lineSpacing = 5.0
// 字符间距
paragraphStyle.paragraphSpacing = 2.0
attributedText.addAttribute(NSParagraphStyleAttributeName, value: paragraphStyle, range: NSRange(location: 0, length: attributedText.length))
label.attributedText = attributedText