CATextLayer.font
property is an opaque CFTypeRef
. Is there a way of converting that reference to a UIFont
? I don't mind if it returns an optional UIFont.
Asked
Active
Viewed 738 times
0

David James
- 2,430
- 1
- 26
- 35
-
1It's `May be either a CTFont, a CGFont, an instance of NSFont (macOS only), or a string naming the font` according to the doc. So https://stackoverflow.com/questions/6714858/iphone-convert-ctfont-to-uifont, https://stackoverflow.com/questions/9205709/how-to-convert-cgfontref-to-uifont etc.? Depending on the type, function equivalent name should be available in Swift. https://stackoverflow.com/questions/3471964/determining-what-a-cftyperef-is to get the type? – Larme Dec 21 '17 at 10:32
-
Since you created the text layer and configured it, how can you not know what font you assigned it? – matt Dec 21 '17 at 17:04
-
Easy. This is part of a general framework, and I use text layers in several places, with different fonts. In fact, my answer below is a modified version of a protocol implementation that requires a `get` and a `set`. No assumptions are made. – David James Dec 21 '17 at 17:19
2 Answers
2
I just wrote the following extension which should handle: CTFont
, CGFont
, string name or UIFont
:
extension CATextLayer {
public var typeFace:UIFont? {
let name:String
switch font {
case let ctFont as CTFont :
// If you assign a UIFont to CATextLayer.font
// it is implicitly converted to CTFont,
// so this case will be called.
guard let _name = CTFontCopyName(ctFont, kCTFontPostScriptNameKey) else {
return nil
}
name = _name as NSString as String
case let cgFont as CGFont :
guard let _name = cgFont.postScriptName else {
return nil
}
name = _name as NSString as String
case let string as NSString :
name = string as String
case let string as String :
name = string
default:
return nil
}
return UIFont(name:name, size:fontSize)
}
}
On a side note, I found this comment in docs inaccurate:
In iOS, you cannot assign a UIFont object to this property.
From my tests I was able to set a UIFont
on CATextLayer.font
and it appears to work fine.
EDIT
It turns out when you assign a UIFont
to CATextLayer.font
it is converted to a CTFont
behind the scenes, so in order to get the UIFont
back out it's necessary to convert from CTFont
to UIFont
(which my code does). Simply casting to UIFont
would not work.

David James
- 2,430
- 1
- 26
- 35
0
You can do like this,
let font : UIFont = layer.font as! UIFont
Hope this helps

Hitesh Sultaniya
- 929
- 1
- 7
- 12
-
This is OK only a UIFont is assigned in the first place, in any other case it will fail. On a side note, I would not force cast, since my return type is `UIFont?` it can just `return self.font as? UIFont`. – David James Dec 21 '17 at 11:25