Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to cast a UIFont object to CTFont in Swift

I'm trying to port some code to Swift that uses UIFont and CTFont, and that (successfully, in Objective-C) uses simple bridged casts to get from one to the other and vice versa.

For example, consider this code (in a UIFontDescriptor category):

UIFont *font = [UIFont fontWithDescriptor:self size:0.0];
NSArray *features = CFBridgingRelease(CTFontCopyFeatures((__bridge CTFontRef)font));

I haven't yet been able to figure out how to express this in Swift in a way that will actually compile. The following at least doesn't:

let font = UIFont(descriptor:self, size: 0.0)
let features = CTFontCopyFeatures(font as CTFont)

Error: 'UIFont' is not convertible to 'CTFont'

like image 563
Christopher Lenz Avatar asked Jun 27 '14 16:06

Christopher Lenz


2 Answers

Try this. You can't just coerce the values from one type to another. If you create a CTFont from the descriptor and size though, it seems to give you a valid array even if you don't include a matrix for transformations (the nil parameter)

let font = CTFontCreateWithFontDescriptor(descriptor, 0.0, nil)
let features: NSArray = CTFontCopyFeatures(font)

As for creating the CTFontDescriptor, I'd use CTFontDescriptorCreateWithNameAndSize or CTFontDescriptorCreateWithAttributes depending on what you're originally given. The latter takes a simple NSDictionary, and the former just uses a font name and size.

To go from an existing font (call it originalFont) just do the following to get a descriptor:

let font = CTFontCreateWithName(originalFont.fontName as CFStringRef, 
    originalFont.pointSize as CGFloat, nil)
like image 131
Dylan Gattey Avatar answered Oct 22 '22 11:10

Dylan Gattey


This has apparently been fixed in a later version of Swift and/or CoreText. At least it works now in my testing using Xcode 7.0.1.

like image 29
Christopher Lenz Avatar answered Oct 22 '22 10:10

Christopher Lenz