简介:
Core Text主要用来对文本进行排版布局和字体处理,与其他UI组件相比,由于它直接与Quartz交互,因此排版效率高,渲染速度快。
下图是Core Text的架构图:
富文本实现:(GitHub传送门)
接下来我们通过一个例子来看看如何实现富文本展示。我们按职责将功能拆分成几个类来完成,
1.一个显示的类,CTDisplayView,仅负责显示。
import UIKit
class CTDisplayView: UIView {
/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
// Drawing code
}
*/
var data:CoreTextData?
override func draw(_ rect: CGRect) {
let context = UIGraphicsGetCurrentContext()
//翻转坐标系
context?.textMatrix = CGAffineTransform.identity
context?.translateBy(x: 0, y: self.bounds.size.height)
context?.scaleBy(x: 1, y: -1)
if data != nil {
CTFrameDraw((self.data?.ctFrame)!, context!)
}
}
}
2.一个配置类,CTFrameParserConfig,负责配置一些默认的参数。
import UIKit
class CTFrameParserConfig: NSObject {
var width:CGFloat = 200.0
var fontName: NSString = "PingFangSC-Regular"
var fontSize: CGFloat = 17.0
var lineSpace: CGFloat = 0.0
var textColor = ColorRGBA(r: 0, g: 0, b: 0, a: 1)
}
3.一个排版类,CTFrameParser,负责实现内容的排版。
class CTFrameParser: NSObject {
// MARK: ------处理模板文件并返回数据源------
class func parserTemplateFlie(_ path: NSString, config: CTFrameParserConfig) -> CoreTextData {
let content = self.loadTemplateFile(path, config: config)
return self.parserAttributedContent(content, config: config)
}
// MARK: ------加载模板文件------
class func loadTemplateFile(_ path: NSString, config: CTFrameParserConfig) -> NSAttributedString {
let data = NSData(contentsOfFile: path as String)
let result = NSMutableAttributedString()
if (data != nil) {
let array:NSArray = try! JSONSerialization.jsonObject(with: data! as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSArray
if array.isKind(of: NSArray.self) {
for dic in array {
if let dict = dic as? NSDictionary {
let type = dict["type"]
if ((type as! NSString).isEqual(to:"txt")) {
let attributedStr = self.parserAttributedContentConvert(dict, config: config)
result.append(attributedStr)
}
}
}
}
}
return result
}
// MARK: ------设置文字模板描述------
class func parserAttributedContentConvert(_ dict: NSDictionary, config: CTFrameParserConfig) -> NSAttributedString {
let attributes:NSMutableDictionary = self.attributes(config) as! NSMutableDictionary
//colorConvert
let colorStr = (dict["color"]) as? String
if (colorStr != nil && colorStr != "default") {
let hexValue = Int(strtoul(colorStr, nil, 16))
let color = ColorHEX(hexValue: hexValue)
attributes.setObject(color, forKey: kCTForegroundColorAttributeName as! NSCopying)
}
//fontConvert
var fontName = dict["fontName"] as? String
var fontSize = dict["fontSize"] as? CGFloat
if (fontName == nil || fontName == "default") {
fontName = config.fontName as String
}
if (fontSize == nil || fontSize! <= 0) {
fontSize = config.fontSize
}
let font = CTFontCreateWithName(fontName as CFString?, fontSize!, nil)
attributes.setObject(font, forKey: kCTFontAttributeName as! NSCopying)
let content = dict["content"] as! NSString
return NSAttributedString(string: content as String, attributes: attributes.copy() as? [String : Any])
}
// MARK: ------设置初始化描述------
class func attributes(_ config: CTFrameP