It's wired, how can i get the foregroundColor use coreText?

let runAttrs = CTRunGetAttributes(ctRun)
var fillColor = unsafeBitCast(CFDictionaryGetValue(runAttrs, unsafeBitCast(kCTBackgroundColorAttributeName, to: UnsafeRawPointer.self)), to: CGColor.self)

Today i was use Core Text to implement vertical text form. but there is a wired problem. i set the attributedString like:

let mStr = NSMutableAttributedString.init(attributedString: str)
			mStr.addAttribute(.kern, value: 2, range: NSMakeRange(0, str.length))
			mStr.addAttribute(.foregroundColor, value: UIColor.yellow, range: NSMakeRange(0, str.length))

but the result was not i expected, i can't get the value about foregroundColor, but the console describe the right structure about runAttrs - a CFDictionary about CTRun

▿ 3 : 2 elements
- key : NSKern
- value : 2
▿ 4 : 2 elements
- key : NSColor
- value : <CGColor 0x283ab2c40> [<CGColorSpace 0x283aa36c0> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; sRGB IEC61966-2.1; extended range)] ( 1 1 0 1 )

Your attributed string has NSAttributedString.Key.foregroundColor, but you're trying to lookup kCTBackgroundColorAttributeName. There's a mismatch between foreground and background, but also between TextKit and CoreText.

Key rawValue
kCTBackgroundColorAttributeName "CTBackgroundColor"
kCTForegroundColorAttributeName "CTForegroundColor"
NSAttributedString.Key.backgroundColor "NSBackgroundColor"
NSAttributedString.Key.foregroundColor "NSColor"

Avoid using the unsafeBitCast function. You can use the type casting operators instead.

let attributes = CTRunGetAttributes(ctRun) as! [NSAttributedString.Key: Any]
let foregroundColor = attributes[.foregroundColor] as! UIColor
assert(foregroundColor == .yellow)

I'm not sure, but I think your kern value should be 2 as NSNumber.

2 Likes
Terms of Service

Privacy Policy

Cookie Policy