iOS 9 まで、CoreText の CTLineDraw などで文字を描画するとき、必要あらば手動で別々に背景色を描いてやる必要がありましたが、iOS 10 では、テキストと一緒に背景が描画できるようになっています。
CoreText Changes for Objective-C を見ると、新しく kCTBackgroundColorAttributeName
が追加されているのが確認できます。
例
単純に NSAttributedString を CTTypesetterCreateWithAttributedString に渡して、CTLine を作って描画してみます。
import UIKit
var attributedText = NSMutableAttributedString(string: "あいうえお", attributes: [
NSForegroundColorAttributeName: UIColor.red,
NSBackgroundColorAttributeName: UIColor.blue
])
let typesetter = CTTypesetterCreateWithAttributedString(attributedText) // NSAttribtedString が CFAttributedString にブリッジして渡される
let ctline = CTTypesetterCreateLine(typesetter, CFRangeMake(0, attributedText.length))
class TestView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor.white
}
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else { return }
context.textPosition = CGPoint(x: 0, y: 20)
context.translateBy(x: 20, y: 20)
CTLineDraw(ctline, context)
}
required init?(coder aDecoder: NSCoder) {}
}
let testView = TestView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
testView

青い背景色が描画されているのが分かります。
弊害と対応策
CoreText (CoreGraphics) と UIKit では座標系が異なる (y軸が逆) ため、ユーザーにとって読みやすくするために、描画対象を上下反転しておく必要があります。(これは今までと同様です)
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else { return }
context.textMatrix = CGAffineTransform(scaleX: 1, y: -1) // ←テキストを上下反転
context.textPosition = CGPoint(x: 0, y: 20)
context.translateBy(x: 20, y: 20)
CTLineDraw(ctline, context)
}
こうすると、テキストの文字列は上下反転しますが、テキストの背景は反転しない罠があります😱
背景はテキストと紐付いているので、同じように動く挙動をするのが自然だと思うのですが、とりあえず、context を scaleBy でまるごと反転することで対応できます。
override func draw(_ rect: CGRect) {
guard let context = UIGraphicsGetCurrentContext() else { return }
context.textPosition = CGPoint(x: 0, y: -20)
context.translateBy(x: 20, y: 20)
context.scaleBy(x: 1, y: -1)
CTLineDraw(ctline, context)
}

上手に描けました