如何从普通的UIFont创建粗体UIFont?

42
如果我有一个UIFont对象,是否可以将其转换为粗体?我不知道字体名称,我只有一个UIFont对象。我想要的是像这样的一个函数:
UIFont *boldFontFromFont(UIFont *input)
{
    return [input derivedFontWithFontWeight:UIFontWeightBold];
}

如何改变这段代码才能使其工作。(上面的代码并不起作用,我只是编造了它来说明问题。)

提前致谢。


@BB9z:真的吗?这个问题是2013年的。现在五年过去了,因为有人再次提出类似的问题,我们应该将其关闭为重复吗? - Michael
我的错误。新的应该被关闭。 - BB9z
@BB9z:或者,我们让两个问题都存在?UIFont.systemFont(ofSize:weight:)方法在2013年并不存在。技术一直在变化。我的问题是:“生活在2013年,我如何从普通的UIFont中创建一个粗体UIFont 在Objective C中?”- 另一个问题是:“生活在2018年,我如何为UILabel设置特定的字体重量 在Swift中”- 如果你这样表达,那就不是同一个问题了。 - Michael
@BB9z:此外,通过字体名称和字体重量创建具有特定字重的字体对象并不意味着要从已有字体对象中创建具有不同字重的字体对象。当问题相似度达到90%时,过于急切地将其关闭为重复问题会让我感到困扰。这对任何人都没有帮助。 - Michael
8个回答

99

iOS 7 引入了一个新的 UIFontDescriptor 类,使得它变得更加容易:

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”

如果您在寻找Cocoa(macOS)的等价物,请注意UIFontDescriptor来自NSFontDescriptor,该类自10.3版本起可用。


28

如果你正在寻找Swift实现

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

希望这能帮助到你!加油!


14

要获得加粗字体,您需要传递来自字体系列的特定字体名称。您可以从给定的字体获取字体系列名称,然后列出该系列中的所有字体。通常,加粗字体名称将包含“bold”,但格式不严格,可能存在变化,例如“Helvetica-BoldOblique”。您可以从以下代码开始:

- (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;
}

嗯,有一个问题:对于systemFont,您的familyName ==“。Helvetica NeueUI”,而fontNames数组为空数组:-/ - Michael
1
@Michael 我尝试了 UIFont *boldFont = [self boldFontFromFont:[UIFont systemFontOfSize:12.0]];。NSLog 输出为:<UICFFont: 0x758b320> font-family: "Helvetica-BoldOblique"; font-weight: bold; font-style: italic; font-size: 12px - filwag
好的,你用的是iOS6吗?因为我用的是iOS5。也许字体系统在iOS6中有所改变了? - Michael
我发现添加一些额外的检查来忽略字体的“斜体”和“压缩”版本也很有用(当然,除非参考字体本身是斜体/压缩)。 - aroth
如果字体除了粗体之外还有更多的权重变化,那么这就会成为一个问题。例如,您可能会有“Helvetica Italic”,“HelveticaBook Italic”,“HelveticaLight Italic”等等。 - Perishable Dave
显示剩余4条评论

9

这是一个非常老的帖子,但是现在有人可能会对如何在Swift 5中执行此操作感兴趣。

就像这样简单:

var font: UIFont = UIFont.systemFont(ofSize: 18)
if let newDescriptor = font.fontDescriptor.withSymbolicTraits(.traitBold) {
    font = UIFont(descriptor: newDescriptor, size: font.pointSize)
}

7

自iOS 7以来,由于系统字体的神秘字体系列名称,使用字体或家族名称尝试推导粗体/斜体字体不再正确。下面是使用UIFontDescriptor类推导粗体/斜体字体的简单扩展。

+(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];
}

这里指出了一个很好的观点:系统字体与其他字体的工作方式并不完全相同。 - iphondroid

2
您可以使用以下方法:
[UIFont boldSystemFontOfSize:12].

如果您正在使用自定义字体,您必须直接使用名称。
[UIFont fontWithName:@"Helvetica-Bold" size:17.0].

你可以使用以下方式查找可能的字体名称:
[UIFont fontNamesForFamilyName:@"American Typewriter"].

在这篇文章中:https://stackoverflow.com/a/15388946/436818,Ben M 提出了一个动态获取加粗版本的想法。但是,为了确保获取到加粗版本(如果存在),需要扩展该方法,因为还有其他加粗版本,比如 CondensedBold。

2

由于在Swift中搜索粗体UIFonts时会弹出此问题,因此这里提供一个最新的回答:


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)
    }
}

例子:

myFont.withSymbolicTraits(.taitBold) // returns the bold version of myFont

1

没有人发表过这样的解决方案:

  • 适用于Swift
  • UIFont的扩展
  • 不使用强制解包
  • 使用与源字体相同的点大小
  • 并且只执行问题中要求的操作(基于现有UIFont创建粗体UIFont

所以我来做:

import UIKit

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

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

随意复制粘贴!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接