k3oirj2
(K3oirj2)
1
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