1

I'd like to get an italic version of a light font, for example "HelveticaNeue-Light".

Using a fontDescriptor gives me the italic version of the 'regular' "Helvetica Neue" instead of the italic "HelveticaNeue-Light". I could retrieve the fontDescriptor.fontAttributes and update the UIFontDescriptor.AttributeName.name, but that's tricky, because the naming is different per font ("HelveticaNeue" uses "Italic", Helvetica uses "Oblique").

let lightFont = UIFont(name: "HelveticaNeue-Light", size: 16.0)!
var lightFontDescriptor = lightFont.fontDescriptor.withSymbolicTraits([.traitItalic])!
var lightFontWithItalicTraits = UIFont(descriptor: lightFontDescriptor, size: 0)

// <UICTFont: ..> font-family: "HelveticaNeue-Light"; font-weight: normal; font-style: normal; font-size: 16.00pt
print(lightFont)

// <UICTFont: ..> font-family: "Helvetica Neue"; font-weight: normal; font-style: italic; font-size: 16.00pt
print(lightFontWithItalicTraits)

// The font I expect:
let lightItalicFont = UIFont(name: "HelveticaNeue-LightItalic", size: 16.0)!
// <UICTFont: ..> font-family: "HelveticaNeue-LightItalic"; font-weight: normal; font-style: italic; font-size: 16.00pt
print(lightItalicFont)

Any other idea how to get the italic version of an existing font?

1 Answer 1

2

It's not the prettiest, but it's functional. It handles all built-in iOS fonts.

Extension:

extension UIFont {
    func italic() -> UIFont? {
        if let italic = UIFont.init(name: "\(self.fontName)-Italic", size: self.pointSize) {
            return italic
        } else if let italic = UIFont.init(name: "\(self.fontName)Italic", size: self.pointSize) {
            return italic
        }
        if let oblique = UIFont.init(name: "\(self.fontName)-Oblique", size: self.pointSize) {
            return oblique
        } else if let oblique = UIFont.init(name: "\(self.fontName)Oblique", size: self.pointSize) {
            return oblique
        }
        var suffixFontName = self.fontName // for font names that have a 2 letter suffix such as ArialMT
        suffixFontName.removeLast(2)
        let suffix = self.fontName.suffix(2)
        if let suffixFontName = UIFont.init(name: "\(suffixFontName)-Italic\(suffix)", size: self.pointSize) {
            return suffixFontName
        }
        if let suffixFontName = UIFont.init(name: "\(suffixFontName)Italic\(suffix)", size: self.pointSize) {
            return suffixFontName
        }
        // no italic, oblique, or mt italic font found
        return nil
    }
}

Usage:

    let helveticaNeueLightItalic = UIFont(name: "HelveticaNeue-Light", size: 16.0)!.italic()
    print(helveticaNeueLightItalic)

    let helveticaItalic = UIFont(name: "Helvetica", size: 16.0)!.italic()
    print(helveticaItalic)

    let helveticaLightItalic = UIFont(name: "Helvetica-Light", size: 16.0)!.italic()
    print(helveticaLightItalic)

    let arialMtItalic = UIFont(name: "ArialMT", size: 16.0)!.italic()
    print(arialMtItalic)

    let arialMtBoldItalic = UIFont(name: "Arial-BoldMT", size: 16.0)!.italic()
    print(arialMtBoldItalic)
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks, I was hoping there's some way to get UIFontDescriptor to do this dirty work. But you're right, this gets the job done and with some unit tests in place it can be future-proofed.
True! Happy to help :-)
suffixFontName isn't really a suffix, it's rather the name without the suffix, suffix which is the foundry, or can be prefix too (LT, MT, A, BT, FB, URW) and not only 2 letters.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.