前提:
1、label需要设置numberOfLines = 0
2、label使用传递进入的size渲染
3、label使用传递进入的富文本渲染
与参考文章差异
1、与UI视图(UILabel)解耦,更方便一些,可以做数据预处理
2、swift版
3、采用元祖回调核心数据(文本信息、单行range)
import CoreText
/// 文本处理工具类
class TextHelper: NSObject {
/// 获取行信息
/// - Parameters:
/// - attributedString: 富文本(文字、行高、字体 and so on...)
/// - size: 所占尺寸
/// - Returns: (当行文本,单行range)
static func getLineInfo(attributedString: NSMutableAttributedString,
size: CGSize) -> [(String, NSRange)]? {
guard let attributes = attributedString.attributes else { return nil }
guard let font = attributes[NSAttributedString.Key.font.rawValue] as? UIFont,
let fontName = font.fontName as? CFString else { return nil }
let text = attributedString.string
let realFont = CTFontCreateWithName(fontName, font.pointSize, nil)
guard let cfAttributedString = attributedString as? CFAttributedString else { return nil }
let frameSetter = CTFramesetterCreateWithAttributedString(cfAttributedString)
let path = CGMutablePath()
path.addRect(CGRect.init(origin: .zero, size: size), transform: .identity)
let frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(CFIndex(0), CFIndex(0)), path, nil)
guard let lines = CTFrameGetLines(frame) as? [CTLine] else { return nil }
var lineArray = [(String, NSRange)]()
for line in lines {
let lineRef = line
var lineRange: CFRange? = CTLineGetStringRange(lineRef)
let range = NSRange(location: lineRange?.location ?? 0, length: lineRange?.length ?? 0)
let lineString = (text as NSString).substring(with: range)
lineArray.append((lineString, range))
}
return lineArray
}
}
参考文章:https://blog.csdn.net/EmulateStep/article/details/78349093