Использование пользовательских шрифтов в конструкторе интерфейса - PullRequest
31 голосов
/ 26 ноября 2010

Я искал этот сайт, но я только нашел вопросы без ответа.

Я загрузил собственный шрифт в свой проект xcode. А [UIFont fontWithName:@"Laconic-Light" size:19] работает. Но построителю интерфейса не нравится шрифт. Я не могу использовать его с IB, он всегда показывает шрифт по умолчанию. Есть ли способ сказать IB, что можно использовать шрифт?

Ответы [ 6 ]

63 голосов
/ 08 июля 2011

У меня также есть эта проблема в Xcode 4. В моей программе есть много UILabel, у которых нет IBOutlets, поэтому я так и делаю;

Во-первых, подкласс от UILabel до CustomFontLabel

Затем переопределите метод "awakeFromNib"

@implementation CustomFontLabel

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

@end

Наконец, в Интерфейсном Разработчике> Identity Inspector измените класс на CustomFontLabel.

5 голосов
/ 28 апреля 2011

Другим решением будет подкласс UILabel для загрузки вашего собственного шрифта. Затем вы можете ссылаться на него в IB, хотя вы по-прежнему не видите нужный шрифт.

3 голосов
/ 11 июня 2014

Благодаря apple, в Xcode 6 у нас есть пользовательские шрифты, доступные в самом конструкторе интерфейсов.

  1. Добавьте файл шрифта .ttf в ваш пакет
  2. Добавьте имя шрифтафайл .plist.
  3. Перейдите в файл xib / storyboard, вы можете увидеть свой шрифт.

enter image description here

3 голосов
/ 22 мая 2014

Вы можете установить этот скрипт http://pitaya.ch/moarfonts/.

У меня действительно хорошо работает с xcode 5.1.1.

3 голосов
/ 17 января 2014

Я предпочитаю делать это несколько более общим способом, который позволит вам изменять размер текста в Интерфейсном Разработчике и просто заменять шрифты во время выполнения.

Я создаю свойство IBCollection для любых элементов UIKit, чтобы установитьшрифт, затем подключите соответствующие элементы из 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]]];
  }];
}
1 голос
/ 29 мая 2014

Swizzle a Font

Решение, как правило, простое, если вы воспользуетесь классом UIFont.Я думаю, что лучше выбрать нормальный шрифт, такой как Helvetica Neue, и переопределить его.Это позволяет вернуть весь проект в стандарт, потянув за отображение.Я уже придумал бурю, чтобы достичь этой цели, когда понял, что кто-то еще сделал это тоже, поэтому я немного помял.Как скажет NSHipster , переполнение может быть опасным, но в этом случае риск довольно низок, учитывая абсолютную простоту UIFont API.В моем случае это было сделано для приложения Enterprise, поэтому риск был еще ниже.

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>
...