在界面构build器中使用自定义字体

我search了这个网站,但是我发现没有答案的问题。

我已经加载了一个自定义字体到我的Xcode项目。 [UIFont fontWithName:@"Laconic-Light" size:19]作品。 但是界面生成器不喜欢字体。 我不能使用IB,它总是显示默认的字体。 有没有办法告诉IB可以使用字体?

我也有这个问题在Xcode 4中。在我的程序中,有很多UILabel没有IBOutlets所以我这样做;

首先,将UILabel子类UILabel CustomFontLabel

然后,重写“ awakeFromNib ”方法

 @implementation CustomFontLabel - (void)awakeFromNib { [super awakeFromNib]; self.font = [UIFont fontWithName:@"CustomFontName" size:self.font.pointSize]; } @end 

最后,在Interface Builder> Identity Inspector中将类更改为CustomFontLabel

另一个解决scheme是将子类UILabel加载到您的自定义字体中。 然后您可以在IB中引用它,但仍然无法看到正确的字体。

我更喜欢用稍微更通用的方式来做到这一点,这让您可以在Interface Builder中调整文本的大小,并在运行时简单地replace字体。

我为任何UIKit元素创build一个IBCollection属性来设置一个字体,然后连接来自IB的适当的项目。

 @property (strong, nonatomic) IBOutletCollection(id) NSArray *lightFontItems; @property (strong, nonatomic) IBOutletCollection(id) NSArray *regularFontItems; 

然后在我看来,加载我使用这样的方法:

 [self setFontName:@"Roboto-Light" onItemsInArray:[self lightFontItems]]; [self setFontName:@"Roboto-Regular" onItemsInArray:[self regularFontItems]]; 

setLightFontOnItemsInArray:方法如下所示:

 + (void)setFontName:(NSString *)fontName onItemsInArray:(NSArray *)array; { [array each:^(id item) { if (![item respondsToSelector:@selector(setFont:)]) return; [item performSelector:@selector(setFont:) withObject:[UIFont fontWithName:fontName size:[[item font] pointSize]]]; }]; } 

你可以安装这个脚本http://pitaya.ch/moarfonts/

用xcode 5.1.1对我来说工作得很好。

感谢苹果,在Xcode 6中,我们在界面生成器本身提供了自定义的字体。

  1. 将.ttf字体文件添加到您的包
  2. 将字体名称添加到.plist文件。
  3. 转到xib / storyboard文件,你可以看到你的字体。

在这里输入图像说明

Swizzle一个字体

如果您调用UIFont类,解决scheme通常很简单。 我认为最好是select一个像Helvetica Neue这样的理智字体,然后重写。 这使您可以通过拉伸映射将整个项目放回到标准中。 当我意识到别人也这样做了,我已经想出了一个实现这个目标的方法,所以我把它弄糊涂了一点。 由于NSHipster会告诉你,调整可能是危险的,但在这种情况下,考虑到UIFont API的绝对简单性,风险相当低。 在我的情况下,这是一个企业应用程序,所以它是更低的风险。

UIFont + CustomFont.m类别

 #import <objc/runtime.h> static NSString *const kFontMapPlist = @"FontMap"; static NSDictionary *_replacementFontDictionary = nil; @implementation UIFont (CustomFont) static void initializeReplacementFonts() { static BOOL initialized = NO; if (initialized) return; initialized = YES; // A Plist with a Dictionary from->to font name mapping NSURL *replacementFontMapURL = [[NSBundle mainBundle] URLForResource:kFontMapPlist withExtension:@"plist"]; NSDictionary *replacementFontMap = [NSDictionary dictionaryWithContentsOfURL:replacementFontMapURL]; [UIFont setReplacementFontDictionary:replacementFontMap]; } + (void)load { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ initializeReplacementFonts(); SEL fontWithNameSizeSelector = @selector(fontWithName:size:); SEL swizzledFontWithNameSizeSelector = @selector(clp_fontWithName:size:); SwizzleClassMethod([UIFont class], fontWithNameSizeSelector, swizzledFontWithNameSizeSelector); SEL fontWithDescriptorSizeSelector = @selector(fontWithDescriptor:size:); SEL swizzledfontWithDescriptorSelector = @selector(clp_fontWithDescriptor:size:); SwizzleClassMethod([UIFont class], fontWithDescriptorSizeSelector, swizzledfontWithDescriptorSelector); }); } void SwizzleClassMethod(Class class, SEL originalSelector, SEL replacementSelector) { Class clazz = objc_getMetaClass(class_getName(class)); Method originalMethod = class_getClassMethod(clazz, originalSelector); Method replacementMethod = class_getClassMethod(clazz, replacementSelector); // Add method if it doesn't eixst BOOL didAddMethod = class_addMethod(clazz, originalSelector, method_getImplementation(replacementMethod), method_getTypeEncoding(replacementMethod)); if (didAddMethod) { class_replaceMethod(clazz, replacementSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); } else { method_exchangeImplementations(originalMethod, replacementMethod); } } #pragma mark - Swizzled font by descriptor and name calls + (UIFont *)clp_fontWithDescriptor:(UIFontDescriptor *)descriptor size:(CGFloat)pointSize { NSString *originalFontName = descriptor.fontAttributes[UIFontDescriptorNameAttribute]; NSString *replacementFontName = _replacementFontDictionary[originalFontName]; UIFontDescriptor *replacementFontDescriptor = descriptor; if (replacementFontName != nil) { replacementFontDescriptor = [UIFontDescriptor fontDescriptorWithFontAttributes:@{UIFontDescriptorNameAttribute: replacementFontName}]; } return [self clp_fontWithDescriptor:replacementFontDescriptor size:pointSize]; } + (UIFont *)clp_fontWithName:(NSString *)fontName size:(CGFloat)fontSize { NSString *replacementFontName = _replacementFontDictionary[fontName]; if (replacementFontName == nil) { replacementFontName = fontName; } return [self clp_fontWithName:replacementFontName size:fontSize]; } #pragma mark - Replacement Dictionary Getter and Setter + (NSDictionary *)replacementDictionary { return _replacementFontDictionary; } + (void)setReplacementFontDictionary:(NSDictionary *)replacmentFontDictionary { if (replacmentFontDictionary == _replacementFontDictionary) { return; } _replacementFontDictionary = replacmentFontDictionary; // Validate font existence. for (NSString *originalFontName in [_replacementFontDictionary allKeys]) { NSString *replacementFontName = [_replacementFontDictionary objectForKey:originalFontName]; UIFont *replacementFont = [UIFont fontWithName:replacementFontName size:10.0f]; if (replacementFont == nil) { DDLogError(@"WARNING: replacement font '%@' is not available.", replacementFontName); } } } @end 

FontMap.plist

为了简单起见,我们假设我们有一个名为CustomSans的字体。

 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>HelveticaNeue-Light</key> <string>CustomSans-Light</string> <key>HelveticaNeue-LightItalic</key> <string>CustomSans-LightItalic</string> <key>HelveticaNeue-Bold</key> <string>CustomSans-Bold</string> <key>HelveticaNeue-BoldItalic</key> <string>CustomSans-BoldItalic</string> </dict> </plist>