42

If I have a UIFont object, is it possible to convert it to bold? I don't know the font name, I just have a UIFont object. What I want is a function like

UIFont *boldFontFromFont(UIFont *input)
{
    return [input derivedFontWithFontWeight:UIFontWeightBold];
}

How can I change the code so that it works. (The code above does not work, I just made it up to illustrate the point.)

Thanks in advance.

Michael
  • 6,451
  • 5
  • 31
  • 53
  • @BB9z: really? this question is from 2013. Should we close it as duplicate now, 5 years later, because someone else asked a similar question again? – Michael Nov 27 '18 at 11:13
  • my mistake. The new one should be closed. – BB9z Nov 28 '18 at 06:07
  • @BB9z: or, alternatively, we let both questions live? The UIFont.systemFont(ofSize:weight:) method did not exist in 2013. Technology changes all the time. My question was "*Living in 2013,* How do I create a bold UIFont from a regular UIFont **in Objective C**?" - the other question is "*Living in 2018,* How do I Set a Specific Font Weight for UILabel **in Swift**" - not really the same if you phrase it this way. – Michael Nov 28 '18 at 15:42
  • @BB9z: also, creating a font object with a specific weight from a font name and a font weight is not the same as wanting to create a font with a different weight from an already existing font object. It bothers me when questions are too eagerly closed as duplicates, just because they are 90% similar. It doesn't help anyone. – Michael Nov 28 '18 at 15:44

8 Answers8

99

iOS 7 introduces a new UIFontDescriptor class, which makes it a lot easier:

UIFont *font = [UIFont fontWithName:@"Helvetica Neue" size:12];
NSLog(@"plain font: %@", font.fontName); // “HelveticaNeue”

UIFont *boldFont = [UIFont fontWithDescriptor:[[font fontDescriptor] fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold] size:font.pointSize];
NSLog(@"bold version: %@", boldFont.fontName); // “HelveticaNeue-Bold”

UIFont *italicFont = [UIFont fontWithDescriptor:[[font fontDescriptor] fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitItalic] size:font.pointSize];
NSLog(@"italic version: %@", italicFont.fontName); // “HelveticaNeue-Italic”

UIFont *boldItalicFont = [UIFont fontWithDescriptor:[[font fontDescriptor] fontDescriptorWithSymbolicTraits:UIFontDescriptorTraitBold | UIFontDescriptorTraitItalic] size:font.pointSize];
NSLog(@"bold & italic version: %@", boldItalicFont.fontName); // “HelveticaNeue-BoldItalic”

For people who got here looking for a Cocoa (macOS) equivalent, UIFontDescriptor comes from NSFontDescriptor, available since 10.3.

marcprux
  • 9,845
  • 3
  • 55
  • 72
28

And if you are looking for the swift implementation:

let normalFont = UIFont(name: "FONT_NAME", size: CGFloat(20))!
let boldFont = UIFont(descriptor: normalFont.fontDescriptor.withSymbolicTraits(.traitBold)!, size: normalFont.pointSize)

Hope this helps! Cheers!

mrh.is
  • 184
  • 3
  • 13
David H.
  • 2,762
  • 1
  • 24
  • 18
14

To get a bold font you need to pass a specific name of the font from a font family. You can get a font family name from a given font, then list all fonts from this family. In general, a bold font will contain "bold" in its name, but the format isn't strict and there could be variations like "Helvetica-BoldOblique", for example. You can start from this code:

- (UIFont *)boldFontFromFont:(UIFont *)font
{
    NSString *familyName = [font familyName];
    NSArray *fontNames = [UIFont fontNamesForFamilyName:familyName];
    for (NSString *fontName in fontNames)
    {
        if ([fontName rangeOfString:@"bold" options:NSCaseInsensitiveSearch].location != NSNotFound)
        {
            UIFont *boldFont = [UIFont fontWithName:fontName size:font.pointSize];
            return boldFont;
        }
    }
    return nil;
}
filwag
  • 690
  • 5
  • 10
  • hmm, there is a problem: for the systemFont, you have familyName == ".Helvetica NeueUI" and the fontNames array is an empty array :-/ – Michael Apr 15 '13 at 13:34
  • 1
    @Michael I've tried `UIFont *boldFont = [self boldFontFromFont:[UIFont systemFontOfSize:12.0]];`. NSLog output is: ` font-family: "Helvetica-BoldOblique"; font-weight: bold; font-style: italic; font-size: 12px` – filwag Apr 15 '13 at 13:47
  • ok, did you use ios6? because i use ios 5. maybe the font system changed in ios6? – Michael Apr 15 '13 at 13:50
  • I get the same result on both iOS5 and iOS6 simulators. – filwag Apr 15 '13 at 13:54
  • on the simulator it works for me too. but on the device it does not. have you tested it on a device as well? – Michael Apr 15 '13 at 14:02
  • @Michael Yep, I got this ".Helvetica NeueUI" on device running iOS6 too. Found this (Twitter, @chockenberry): `iPhoneDevProtip: iPhone 4 system font is ".Helvetica NeueUI" with different lineHeight, ascender, descender metrics than "Helvetica Neue".`. Workaround: https://github.com/schwa/CoreTextToy/pull/35/files – filwag Apr 15 '13 at 14:11
  • omg, this is ugly. but it works, so I'll accept it. thanks. `if(font == [UIFont systemFontOfSize:font.pointSize]) { return [UIFont boldSystemFontOfSize:font.pointSize]; } else if(font == [UIFont boldSystemFontOfSize:font.pointSize]) { return font; }` – Michael Apr 15 '13 at 14:28
  • I also found it useful to add some extra checks to ignore 'italic' and 'condensed' versions of the font (unless, of course, the reference font is itself italic/condensed). – aroth May 19 '14 at 07:06
  • This is problematic if you have more weight variations for a font than just bold. For example you could have "Helvetica Italic", "HelveticaBook Italic", "HelveticaLight Italic", etc. – Perishable Dave Mar 13 '15 at 00:01
9

This is a very old thread but someone may be interested in how to do this in Swift 5 nowadays.

Easy like this:

var font: UIFont = UIFont.systemFont(ofSize: 18)
if let newDescriptor = font.fontDescriptor.withSymbolicTraits(.traitBold) {
    font = UIFont(descriptor: newDescriptor, size: font.pointSize)
}
Joachim Deelen
  • 1,021
  • 10
  • 8
7

Attempting to derive the bold/italic font using font or family names no longer works correctly since iOS 7, due to the cryptic font family name of the system font. Below is a simple extension to derive the bold/italic font using the UIFontDescriptor class.

+(UIFont *) font:(UIFont *)font bold:(BOOL)bold italic:(BOOL)italic
{
    NSUInteger traits = 0;
    if (bold)
    {
        traits |= UIFontDescriptorTraitBold;
    }
    if (italic)
    {
        traits |= UIFontDescriptorTraitItalic;
    }
    return [UIFont fontWithDescriptor:[[font fontDescriptor] fontDescriptorWithSymbolicTraits:traits] size:font.pointSize];
}
loungerdork
  • 991
  • 11
  • 15
2

You can either use

[UIFont boldSystemFontOfSize:12].

If you are using custom fonts you have to use the name directly

[UIFont fontWithName:@"Helvetica-Bold" size:17.0].

You can look up the possible font names with

[UIFont fontNamesForFamilyName:@"American Typewriter"].

In this Post: https://stackoverflow.com/a/15388946/436818 Ben M has an idea how to get the bold version dynamically. But extend the method to be sure to get the bold version (if it exists) because there are other bold versions like CondensedBold too.

Community
  • 1
  • 1
user436818
  • 267
  • 1
  • 3
  • 11
2

Since this question pops up when you search for bold UIFonts in Swift, here's a fresh answer:

extension UIFont {
    /// Returns a new font in the same family with the given symbolic traits,
    /// or `nil` if none found in the system.
    func withSymbolicTraits(_ traits: UIFontDescriptor.SymbolicTraits) -> UIFont? {
        guard let descriptorWithTraits = fontDescriptor.withSymbolicTraits(traits)
            else { return nil }
        return UIFont(descriptor: descriptorWithTraits, size: 0)
    }
}

Example:

myFont.withSymbolicTraits(.taitBold) // returns the bold version of myFont
Nikita Kukushkin
  • 14,648
  • 4
  • 37
  • 45
1

Nobody posted a solution which:

  • is for Swift
  • is an extension for UIFont
  • doesn't do force unwraps
  • uses the same point size as source font
  • and only does what is asked in the question (create bold UIFont based on existing UIFont)

so I'm doing it:

import UIKit

extension UIFont {
    func boldFont() -> UIFont? {
        guard let boldDescriptor = fontDescriptor.withSymbolicTraits(.traitBold) else {
            return nil
        }

        return UIFont(descriptor: boldDescriptor, size: pointSize)
    }
}

Feel free to copy-and-paste!

ivanzoid
  • 5,952
  • 2
  • 34
  • 43