Установить шрифт по умолчанию для всего приложения iOS?

У меня есть собственный шрифт, который я хочу использовать для отображения текста в приложении, надписей, текстовых представлений и т.д.

Есть ли способ установить шрифт по умолчанию (метки по умолчанию используют SystemFont) для всего приложения?

4b9b3361

В iOS 5 возможно использование прокси-сервера UIAppearance.

 [[UILabel appearance] setFont:[UIFont fontWithName:@"YourFontName" size:17.0]];

Это установит шрифт как ваш собственный шрифт для всех UILabels в вашем приложении. Вам нужно будет повторить его для каждого элемента управления (UIButton, UILabel и т.д.).

Помните, что вам нужно поместить значение UIAppFonts в свой info.plist и включить имя шрифта, который вы включаете.

155
ответ дан 03 янв. '12 в 8:10
источник

Существует также другое решение, которое должно переопределить systemFont.

Просто создайте категорию

UIFont + SystemFontOverride.h

#import <UIKit/UIKit.h>

@interface UIFont (SystemFontOverride)
@end

UIFont + SystemFontOverride.m

@implementation UIFont (SystemFontOverride)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"

+ (UIFont *)boldSystemFontOfSize:(CGFloat)fontSize {
    return [UIFont fontWithName:@"fontName" size:fontSize];
}

+ (UIFont *)systemFontOfSize:(CGFloat)fontSize {
    return [UIFont fontWithName:@"fontName" size:fontSize];
}

#pragma clang diagnostic pop

@end

Это заменит реализацию по умолчанию, и большинство UIControls используют systemFont.

74
ответ дан 31 июля '13 в 20:46
источник

Swift 4.1

Основываясь на ответе Фабио Оливейры (qaru.site/info/49059/...), я делаю свой собственный быстрый 4.

Короче говоря, это расширение обменивается стандартными функциями init(coder:), systemFont(ofSize:), boldSystemFont(ofSize:), italicSystemFont(ofSize:) с моими пользовательскими методами.

Обратите внимание, что он не полностью реализуется, но вы можете обменивать больше методов на мою реализацию.

import UIKit

struct AppFontName {
    static let regular = "CourierNewPSMT"
    static let bold = "CourierNewPS-BoldMT"
    static let italic = "CourierNewPS-ItalicMT"
}

extension UIFontDescriptor.AttributeName {
    static let nsctFontUIUsage = UIFontDescriptor.AttributeName(rawValue: "NSCTFontUIUsageAttribute")
}

extension UIFont {

    @objc class func mySystemFont(ofSize size: CGFloat) -> UIFont {
        return UIFont(name: AppFontName.regular, size: size)!
    }

    @objc class func myBoldSystemFont(ofSize size: CGFloat) -> UIFont {
        return UIFont(name: AppFontName.bold, size: size)!
    }

    @objc class func myItalicSystemFont(ofSize size: CGFloat) -> UIFont {
        return UIFont(name: AppFontName.italic, size: size)!
    }

    @objc convenience init(myCoder aDecoder: NSCoder) {
        guard
            let fontDescriptor = aDecoder.decodeObject(forKey: "UIFontDescriptor") as? UIFontDescriptor,
            let fontAttribute = fontDescriptor.fontAttributes[.nsctFontUIUsage] as? String else {
                self.init(myCoder: aDecoder)
                return
        }
        var fontName = ""
        switch fontAttribute {
        case "CTFontRegularUsage":
            fontName = AppFontName.regular
        case "CTFontEmphasizedUsage", "CTFontBoldUsage":
            fontName = AppFontName.bold
        case "CTFontObliqueUsage":
            fontName = AppFontName.italic
        default:
            fontName = AppFontName.regular
        }
        self.init(name: fontName, size: fontDescriptor.pointSize)!
    }

    class func overrideInitialize() {
        guard self == UIFont.self else { return }

        if let systemFontMethod = class_getClassMethod(self, #selector(systemFont(ofSize:))),
            let mySystemFontMethod = class_getClassMethod(self, #selector(mySystemFont(ofSize:))) {
            method_exchangeImplementations(systemFontMethod, mySystemFontMethod)
        }

        if let boldSystemFontMethod = class_getClassMethod(self, #selector(boldSystemFont(ofSize:))),
            let myBoldSystemFontMethod = class_getClassMethod(self, #selector(myBoldSystemFont(ofSize:))) {
            method_exchangeImplementations(boldSystemFontMethod, myBoldSystemFontMethod)
        }

        if let italicSystemFontMethod = class_getClassMethod(self, #selector(italicSystemFont(ofSize:))),
            let myItalicSystemFontMethod = class_getClassMethod(self, #selector(myItalicSystemFont(ofSize:))) {
            method_exchangeImplementations(italicSystemFontMethod, myItalicSystemFontMethod)
        }

        if let initCoderMethod = class_getInstanceMethod(self, #selector(UIFontDescriptor.init(coder:))), // Trick to get over the lack of UIFont.init(coder:))
            let myInitCoderMethod = class_getInstanceMethod(self, #selector(UIFont.init(myCoder:))) {
            method_exchangeImplementations(initCoderMethod, myInitCoderMethod)
        }
    }
}


class AppDelegate: UIResponder, UIApplicationDelegate {
    // Avoid warning of Swift
    // Method 'initialize()' defines Objective-C class method 'initialize', which is not guaranteed to be invoked by Swift and will be disallowed in future versions
    override init() {
        super.init()
        UIFont.overrideInitialize()
    }
    ...
}
62
ответ дан 08 нояб. '16 в 13:23
источник

Если вы используете Swift, вы можете создать расширение UILabel:

extension UILabel {

    var substituteFontName : String {
        get { return self.font.fontName }
        set { self.font = UIFont(name: newValue, size: self.font.pointSize) }
    }

}

И затем, когда вы делаете свое проксирование:

UILabel.appearance().substituteFontName = applicationFont

Существует эквивалентный код Objective-C, используя UI_APPEARANCE_SELECTOR для свойства с именем substituteFontName.

Добавление

В случае, если вы хотите установить жирный шрифт и обычные шрифты отдельно:

extension UILabel {

    var substituteFontName : String {
        get { return self.font.fontName }
        set { 
            if self.font.fontName.range(of:"Medium") == nil { 
                self.font = UIFont(name: newValue, size: self.font.pointSize)
            }
        }
    }

    var substituteFontNameBold : String {
        get { return self.font.fontName }
        set { 
            if self.font.fontName.range(of:"Medium") != nil { 
                self.font = UIFont(name: newValue, size: self.font.pointSize)
            }
        }
    }
}

Затем для ваших прокси-серверов UIAppearance:

UILabel.appearance().substituteFontName = applicationFont
UILabel.appearance().substituteFontNameBold = applicationFontBold

Примечание. Если вы обнаружите, что полужирная подстановка не работает, возможно, имя шрифта по умолчанию не содержит "Medium". Выключите эту строку для другого соответствия по мере необходимости (спасибо Mason в комментариях ниже).

58
ответ дан 10 февр. '15 в 22:57
источник

Разработка из Hugues BR ответа, но с использованием метода swizzling Я пришел к решению, которое успешно меняет все шрифты на желаемый шрифт в моем приложении.

Подход с динамическим типом должен быть тем, что вы должны искать на iOS 7. Следующее решение не использует Dynamic Type.


Примечания:

  • приведенный ниже код в его представленном состоянии никогда не был представлен на утверждение Apple;
  • есть более короткая версия, которая передала представление Apple, без переопределения - initWithCoder:. Однако это не будет охватывать все случаи;
  • следующий код присутствует в классе, который я использую для установки стиля моего приложения, которое включено моим классом AppDelegate, таким образом, доступным везде и для всех экземпляров UIFont;
  • Я использую Zapfino здесь, чтобы сделать изменения более заметными;
  • любое улучшение, которое вы можете найти в этом коде, приветствуется.

Это решение использует два разных метода для достижения конечного результата. Первая переопределяет методы класса UIFont + systemFontWithSize: и аналогична тем, которые используют мои альтернативы (здесь я использую "Zapfino", чтобы не сомневаться, что замена прошла успешно).

Другой метод - переопределить метод - initWithCoder: в UIFont, чтобы заменить любое событие CTFontRegularUsage и подобное по моим альтернативам. Этот последний метод был необходим, потому что я обнаружил, что объекты UILabel, закодированные в файлах NIB, не проверяют методы + systemFontWithSize: для получения их системного шрифта и вместо этого кодируют их как объекты UICTFontDescriptor. Я попытался переопределить - awakeAfterUsingCoder:, но каким-то образом он вызывался для каждого закодированного объекта в моем раскадровке и вызывал сбои. Переопределение - awakeFromNib не позволило бы мне прочитать объект NSCoder.

#import <objc/runtime.h>

NSString *const FORegularFontName = @"Zapfino";
NSString *const FOBoldFontName = @"Zapfino";
NSString *const FOItalicFontName = @"Zapfino";

#pragma mark - UIFont category
@implementation UIFont (CustomFonts)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-protocol-method-implementation"
+ (void)replaceClassSelector:(SEL)originalSelector withSelector:(SEL)modifiedSelector {
    Method originalMethod = class_getClassMethod(self, originalSelector);
    Method modifiedMethod = class_getClassMethod(self, modifiedSelector);
    method_exchangeImplementations(originalMethod, modifiedMethod);
}

+ (void)replaceInstanceSelector:(SEL)originalSelector withSelector:(SEL)modifiedSelector {
    Method originalDecoderMethod = class_getInstanceMethod(self, originalSelector);
    Method modifiedDecoderMethod = class_getInstanceMethod(self, modifiedSelector);
    method_exchangeImplementations(originalDecoderMethod, modifiedDecoderMethod);
}

+ (UIFont *)regularFontWithSize:(CGFloat)size
{
    return [UIFont fontWithName:FORegularFontName size:size];
}

+ (UIFont *)boldFontWithSize:(CGFloat)size
{
    return [UIFont fontWithName:FOBoldFontName size:size];
}

+ (UIFont *)italicFontOfSize:(CGFloat)fontSize
{
    return [UIFont fontWithName:FOItalicFontName size:fontSize];
}

- (id)initCustomWithCoder:(NSCoder *)aDecoder {
    BOOL result = [aDecoder containsValueForKey:@"UIFontDescriptor"];

    if (result) {
        UIFontDescriptor *descriptor = [aDecoder decodeObjectForKey:@"UIFontDescriptor"];

        NSString *fontName;
        if ([descriptor.fontAttributes[@"NSCTFontUIUsageAttribute"] isEqualToString:@"CTFontRegularUsage"]) {
            fontName = FORegularFontName;
        }
        else if ([descriptor.fontAttributes[@"NSCTFontUIUsageAttribute"] isEqualToString:@"CTFontEmphasizedUsage"]) {
            fontName = FOBoldFontName;
        }
        else if ([descriptor.fontAttributes[@"NSCTFontUIUsageAttribute"] isEqualToString:@"CTFontObliqueUsage"]) {
            fontName = FOItalicFontName;
        }
        else {
            fontName = descriptor.fontAttributes[@"NSFontNameAttribute"];
        }

        return [UIFont fontWithName:fontName size:descriptor.pointSize];
    }

    self = [self initCustomWithCoder:aDecoder];

    return self;
}

+ (void)load
{
    [self replaceClassSelector:@selector(systemFontOfSize:) withSelector:@selector(regularFontWithSize:)];
    [self replaceClassSelector:@selector(boldSystemFontOfSize:) withSelector:@selector(boldFontWithSize:)];
    [self replaceClassSelector:@selector(italicSystemFontOfSize:) withSelector:@selector(italicFontOfSize:)];

    [self replaceInstanceSelector:@selector(initWithCoder:) withSelector:@selector(initCustomWithCoder:)];
}
#pragma clang diagnostic pop

@end
22
ответ дан 13 апр. '14 в 15:23
источник

Чтобы завершить ответ Sandy Chapman, вот решение в Objective-C (поместите эту категорию в любом месте, где хотите изменить UILabel Appearance):

@implementation UILabel (FontOverride)
- (void)setSubstituteFontName:(NSString *)name UI_APPEARANCE_SELECTOR {
    self.font = [UIFont fontWithName:name size:self.font.pointSize];
}
@end

Файл интерфейса должен иметь этот метод, объявленный публично для использования позже из таких мест, как ваш делегат приложения:

@interface UILabel (FontOverride)
  - (void)setSubstituteFontName:(NSString *)name UI_APPEARANCE_SELECTOR;
@end

Затем вы можете изменить Appearance с помощью:

[[UILabel appearance] setSubstituteFontName:@"SourceSansPro-Light"];
13
ответ дан 16 апр. '15 в 16:50
источник

Я опубликовал его как новый ответ, а не как комментарий, потому что у меня недостаточно репутации.

КОММЕНТАРИЙ ДЛЯ SWIFT 3.0 И ПРЕДУПРЕЖДЕНИЕ SWIFT

Вы можете удалить предупреждающее сообщение в строке:

let initCoderMethod = class_getInstanceMethod(self, Selector("initWithCoder:"))

Заменив его:

let initCoderMethod = class_getInstanceMethod(self, #selector(UIFontDescriptor.init(coder:)))
4
ответ дан 15 февр. '17 в 4:08
источник

Для Swift 4

Все приведенные выше ответы верны, но я сделал несколько иначе, что соответствует размеру устройства. Здесь, в классе ATFontManager, я сделал размер шрифта по умолчанию, который определяется в верхней части класса как defaultFontSize, это размер шрифта iphone plus, и вы можете изменить его в соответствии с вашими требованиями.

     class ATFontManager: UIFont{

    class func setFont( _ iPhone7PlusFontSize: CGFloat? = nil,andFontName fontN : String = FontName.HelveticaNeue) -> UIFont{

        let defaultFontSize : CGFloat = 16

        switch ATDeviceDetector().screenType {

        case .iPhone4:
            if let fontSize = iPhone7PlusFontSize{
                return UIFont(name: fontN, size: fontSize - 3)!
            }
            return UIFont(name: fontN, size: defaultFontSize - 6)!

        case .iPhone5:
            if let fontSize = iPhone7PlusFontSize{
                return UIFont(name: fontN, size: fontSize - 2)!
            }
            return UIFont(name: fontN, size: defaultFontSize - 3)!

        case .iPhone6AndIphone7:
            if let fontSize = iPhone7PlusFontSize{
                return UIFont(name: fontN, size: fontSize - 1)!
            }
            return UIFont(name: fontN, size: defaultFontSize - 1)!

        case .iPhone6PAndIPhone7P:

            return UIFont(name: fontN, size: iPhone7PlusFontSize ?? defaultFontSize)!
        case .iPhoneX:

            return UIFont(name: fontN, size: iPhone7PlusFontSize ?? defaultFontSize)!

        case .iPhoneOrIPadSmallSizeUnknown:

            return UIFont(name: fontN, size: iPhone7PlusFontSize ?? defaultFontSize)!

        case .iPadMini:
            if let fontSize = iPhone7PlusFontSize{
                return UIFont(name: fontN, size: fontSize + 4)!
            }
            return UIFont(name: fontN, size: defaultFontSize + 4)!

        case .iPadPro10Inch:
            if let fontSize = iPhone7PlusFontSize{
                return UIFont(name: fontN, size: fontSize + 5)!
            }
            return UIFont(name: fontN, size: defaultFontSize + 5)!

        case .iPadPro:
            if let fontSize = iPhone7PlusFontSize{
                return UIFont(name: fontN, size: fontSize + 6)!
            }
            return UIFont(name: fontN, size: defaultFontSize + 6)!

        case .iPadUnknown:

            return UIFont(name: fontN, size: defaultFontSize + 3)!

        default:

            return UIFont(name: fontN, size: iPhone7PlusFontSize ?? 15)!
        }
    }
}

Я добавил определенное имя шрифта, поскольку вы можете добавить имя шрифта и ввести его здесь.

   enum FontName : String {
        case HelveticaNeue = "HelveticaNeue"
        case HelveticaNeueUltraLight = "HelveticaNeue-UltraLight"
        case HelveticaNeueBold = "HelveticaNeue-Bold"
        case HelveticaNeueBoldItalic = "HelveticaNeue-BoldItalic"
        case HelveticaNeueMedium = "HelveticaNeue-Medium"
        case AvenirBlack = "Avenir-Black"
        case ArialBoldMT = "Arial-BoldMT"
        case HoeflerTextBlack = "HoeflerText-Black"
        case AMCAPEternal = "AMCAPEternal"
    }

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

class ATDeviceDetector {

    var iPhone: Bool {

        return UIDevice().userInterfaceIdiom == .phone
    }

    var ipad : Bool{

        return UIDevice().userInterfaceIdiom == .pad
    }

    let isRetina = UIScreen.main.scale >= 2.0


    enum ScreenType: String {

        case iPhone4
        case iPhone5
        case iPhone6AndIphone7
        case iPhone6PAndIPhone7P
        case iPhoneX

        case iPadMini
        case iPadPro
        case iPadPro10Inch

        case iPhoneOrIPadSmallSizeUnknown
        case iPadUnknown
        case unknown
    }


    struct ScreenSize{

        static let SCREEN_WIDTH         = UIScreen.main.bounds.size.width
        static let SCREEN_HEIGHT        = UIScreen.main.bounds.size.height
        static let SCREEN_MAX_LENGTH    = max(ScreenSize.SCREEN_WIDTH,ScreenSize.SCREEN_HEIGHT)
        static let SCREEN_MIN_LENGTH    = min(ScreenSize.SCREEN_WIDTH,ScreenSize.SCREEN_HEIGHT)
    }


    var screenType: ScreenType {

        switch ScreenSize.SCREEN_MAX_LENGTH {

        case 0..<568.0:
            return .iPhone4
        case 568.0:
            return .iPhone5
        case 667.0:
            return .iPhone6AndIphone7
        case 736.0:
            return .iPhone6PAndIPhone7P
        case 812.0:
            return .iPhoneX
        case 568.0..<812.0:
            return .iPhoneOrIPadSmallSizeUnknown
        case 1112.0:
            return .iPadPro10Inch
        case 1024.0:
            return .iPadMini
        case 1366.0:
            return .iPadPro
        case 812.0..<1366.0:
            return .iPadUnknown
        default:
            return .unknown
        }
    }
}

Как пользоваться. Надеюсь, это поможет.

//for default 
label.font = ATFontManager.setFont()

//if you want to provide as your demand. Here **iPhone7PlusFontSize** variable is denoted as font size for *iphone 7plus and iphone 6 plus*, and it **ATFontManager** class automatically handle.
label.font = ATFontManager.setFont(iPhone7PlusFontSize: 15, andFontName: FontName.HelveticaNeue.rawValue)
3
ответ дан 10 авг. '17 в 7:32
источник

Ни одно из этих решений не работает повсеместно в приложении. Одна вещь, которую я нашел, чтобы помочь управлять шрифтами в Xcode, открывает раскадровку как исходный код (Control-click раскадровка в Навигаторе файлов > "Открыть как" > "Источник" ), а затем выполняет поиск и замену.

2
ответ дан 25 июня '14 в 22:15
источник

Вероятно, нет, скорее всего, у вас будет установлен шрифт на вашем элементе управления, но вы можете сделать процесс проще, централизуя, где вы получаете типы шрифтов, например, делегат приложения или какой-либо другой общий класс имеют метод который возвращает шрифт, и все, что нужно для установки шрифта, может вызвать этот метод, который поможет в случае необходимости изменения шрифта, вы можете изменить его в одном месте, а не везде, где вы устанавливаете шрифты... Еще одна альтернатива может быть создайте подклассы ваших элементов интерфейса, которые будут автоматически устанавливать шрифт, но это может быть излишним.

2
ответ дан 03 янв. '12 в 6:18
источник

Тип шрифта всегда устанавливается в коде и nib/раскадровке.

Для кода, как и Hugues BR сказал, сделать это в catagory может решить проблему.

Для nib/раскадровки мы можем использовать метод Swizzling awakeFromNib для изменения типа шрифта, поскольку элемент пользовательского интерфейса из nib/раскадровки всегда вызывает его перед показом на экране.

Я полагаю, вы знаете Aspects. Это библиотека для программирования АОП, основанная на методе Swizzling. Мы создаем каталоги для UILabel, UIButton, UITextView для ее реализации.

UILabel:

#import "UILabel+OverrideBaseFont.h"
#import "Aspects.h"

@implementation UILabel (OverrideBaseFont)

+ (void)load {
    [[self class]aspect_hookSelector:@selector(awakeFromNib) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> aspectInfo) {
        UILabel* instance = [aspectInfo instance];
        UIFont* font = [UIFont fontWithName:@"HelveticaNeue-light" size:instance.font.pointSize];
        instance.font = font;
    }error:nil];
}

@end

UIButton:

#import "UIButton+OverrideBaseFont.h"
#import "Aspects.h"

@implementation UIButton (OverrideBaseFont)

+ (void)load {
    [[self class]aspect_hookSelector:@selector(awakeFromNib) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> aspectInfo) {
        UIButton* instance = [aspectInfo instance];
        UILabel* label = instance.titleLabel;
        UIFont* font = [UIFont fontWithName:@"HelveticaNeue-light" size:label.font.pointSize];
        instance.titleLabel.font = font;
    }error:nil];
}

@end

UITextField:

#import "UITextField+OverrideBaseFont.h"
#import "Aspects.h"

@implementation UITextField (OverrideBaseFont)

+ (void)load {
    [[self class]aspect_hookSelector:@selector(awakeFromNib) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> aspectInfo) {
        UITextField* instance = [aspectInfo instance];
        UIFont* font = [UIFont fontWithName:@"HelveticaNeue-light" size:instance.font.pointSize];
        instance.font = font;
    }error:nil];
}

@end

UITextView:

#import "UITextView+OverrideBaseFont.h"
#import "Aspects.h"

@implementation UITextView (OverrideBaseFont)

+ (void)load {
    [[self class]aspect_hookSelector:@selector(awakeFromNib) withOptions:AspectPositionAfter usingBlock:^(id<AspectInfo> aspectInfo) {
        UITextView* instance = [aspectInfo instance];
        UIFont* font = [UIFont fontWithName:@"HelveticaNeue-light" size:instance.font.pointSize];
        instance.font = font;
    }error:nil];
}

@end

Чтобы все это, вы можете изменить HelveticaNeue-light на макрос с вашим именем шрифта.

2
ответ дан 26 нояб. '15 в 12:25
источник

NUI является альтернативой прокси-серверу UIAppearance. Это дает вам контроль над шрифтом (и многими другими атрибутами) большого количества типов элементов пользовательского интерфейса во всем приложении, просто изменяя таблицу стилей, которую можно использовать повторно в нескольких приложениях.

После добавления класса NUILabel к вашим меткам вы можете легко управлять своим шрифтом в таблице стилей:

LabelFontName    String    Helvetica

Если у вас есть метки с разными размерами шрифтов, вы можете контролировать их размеры с помощью классов NUI Label, LargeLabel и SmallLabel или даже быстро создавать свои собственные классы.

1
ответ дан 27 нояб. '12 в 22:11
источник

Я использую подобный класс шрифтов в swift. Использование класса расширения шрифтов.

enum FontName: String {

  case regular      = "Roboto-Regular"

}

//MARK: - Set Font Size
enum FontSize: CGFloat {
    case size = 10

}
extension UIFont {

    //MARK: - Bold Font
  class var regularFont10: UIFont {
        return UIFont(name: FontName.regular.rawValue, size:FontSize.size.rawValue )!
    }
}
0
ответ дан 30 янв. '18 в 15:03
источник

Для Xamarin.iOS внутри AppDelegate FinishedLaunching() введите код следующим образом:

UILabel.Appearance.Font= UIFont.FromName("Lato-Regular", 14);

установите шрифт для всего приложения и UIAppFonts ключ " UIAppFonts " в Info.plist, путь должен быть тем местом, где расположен ваш файл шрифта.ttf. Для меня это было внутри папки "fonts" в моем проекте.

<key>UIAppFonts</key>
    <array>
        <string>fonts/Lato-Regular.ttf</string>
    </array>
0
ответ дан 19 сент. '18 в 15:30
источник

Я создал собственное преобразование типографики для Swift 4 после рассмотрения нескольких сообщений, оно охватывает большинство случаев, таких как:

struct Resources {

    struct Fonts {
        //struct is extended in Fonts
    }
}

extension Resources.Fonts {

    enum Weight: String {
        case light = "Typo-Light"
        case regular = "Typo-Regular"
        case semibold = "Typo-Semibold"
        case italic = "Typo-LightItalic"
    }
}

extension UIFontDescriptor.AttributeName {
    static let nsctFontUIUsage = UIFontDescriptor.AttributeName(rawValue: "NSCTFontUIUsageAttribute")
}

extension UIFont {

    @objc class func mySystemFont(ofSize: CGFloat, weight: UIFont.Weight) -> UIFont {
        switch weight {
        case .semibold, .bold, .heavy, .black:
            return UIFont(name: Resources.Fonts.Weight.semibold.rawValue, size: ofSize)!

        case .medium, .regular:
            return UIFont(name: Resources.Fonts.Weight.regular.rawValue, size: ofSize)!

        default:
            return UIFont(name: Resources.Fonts.Weight.light.rawValue, size: ofSize)!
        }
    }

    @objc class func mySystemFont(ofSize size: CGFloat) -> UIFont {
        return UIFont(name: Resources.Fonts.Weight.light.rawValue, size: size)!
    }

    @objc class func myBoldSystemFont(ofSize size: CGFloat) -> UIFont {
        return UIFont(name: Resources.Fonts.Weight.semibold.rawValue, size: size)!
    }

    @objc class func myItalicSystemFont(ofSize size: CGFloat) -> UIFont {
        return UIFont(name: Resources.Fonts.Weight.italic.rawValue, size: size)!
    }

    @objc convenience init(myCoder aDecoder: NSCoder) {
        guard
            let fontDescriptor = aDecoder.decodeObject(forKey: "UIFontDescriptor") as? UIFontDescriptor,
            let fontAttribute = fontDescriptor.fontAttributes[.nsctFontUIUsage] as? String else {
                self.init(myCoder: aDecoder)
                return
        }
        var fontName = ""
        switch fontAttribute {
        case "CTFontRegularUsage", "CTFontMediumUsage":
            fontName = Resources.Fonts.Weight.regular.rawValue
        case "CTFontEmphasizedUsage", "CTFontBoldUsage", "CTFontSemiboldUsage","CTFontHeavyUsage", "CTFontBlackUsage":
            fontName = Resources.Fonts.Weight.semibold.rawValue
        case "CTFontObliqueUsage":
            fontName = Resources.Fonts.Weight.italic.rawValue
        default:
            fontName = Resources.Fonts.Weight.light.rawValue
        }
        self.init(name: fontName, size: fontDescriptor.pointSize)!
    }

    class func overrideDefaultTypography() {
        guard self == UIFont.self else { return }

        if let systemFontMethodWithWeight = class_getClassMethod(self, #selector(systemFont(ofSize: weight:))),
            let mySystemFontMethodWithWeight = class_getClassMethod(self, #selector(mySystemFont(ofSize: weight:))) {
            method_exchangeImplementations(systemFontMethodWithWeight, mySystemFontMethodWithWeight)
        }

        if let systemFontMethod = class_getClassMethod(self, #selector(systemFont(ofSize:))),
            let mySystemFontMethod = class_getClassMethod(self, #selector(mySystemFont(ofSize:))) {
            method_exchangeImplementations(systemFontMethod, mySystemFontMethod)
        }

        if let boldSystemFontMethod = class_getClassMethod(self, #selector(boldSystemFont(ofSize:))),
            let myBoldSystemFontMethod = class_getClassMethod(self, #selector(myBoldSystemFont(ofSize:))) {
            method_exchangeImplementations(boldSystemFontMethod, myBoldSystemFontMethod)
        }

        if let italicSystemFontMethod = class_getClassMethod(self, #selector(italicSystemFont(ofSize:))),
            let myItalicSystemFontMethod = class_getClassMethod(self, #selector(myItalicSystemFont(ofSize:))) {
            method_exchangeImplementations(italicSystemFontMethod, myItalicSystemFontMethod)
        }

        if let initCoderMethod = class_getInstanceMethod(self, #selector(UIFontDescriptor.init(coder:))),
            let myInitCoderMethod = class_getInstanceMethod(self, #selector(UIFont.init(myCoder:))) {
            method_exchangeImplementations(initCoderMethod, myInitCoderMethod)
        }
    }
}

Наконец, вызовите созданный метод в Appdelegate следующим образом:

class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {

        UIFont.overrideDefaultTypography()
        return true
    }
}
0
ответ дан 01 окт. '18 в 16:31
источник

Мы получили то же самое в Swift -Xcode 7.2, используя Parent View Controller и Child view controller (Наследование).

Файл - Новый - Cocoa Класс Touch - ParentViewController.

    import UIKit
    import Foundation

    class ParentViewController: UIViewController {

        var appUIColor:UIColor = UIColor.redColor()
        var appFont:UIFont = UIFont(name: "Copperplate", size: 20)!

        override func viewDidLoad() {
            super.viewDidLoad()
        }
        func addStatusBar()
        {
            let view = UIView(frame:
                CGRect(x: 0.0, y: 0.0, width: UIScreen.mainScreen().bounds.size.width, height: 20.0)
            )
            view.backgroundColor = appUIColor
            self.view.addSubview(view)
        }
    }    

Создайте дочерние контроллеры и свяжите их с VC StoryBoard, добавьте textLabel.

    import UIKit

    class FontTestController: ParentViewController {
        @IBOutlet var testLabel: UILabel!

        override func viewDidLoad() {
            super.viewDidLoad()
            testLabel.font =  appFont
            testLabel.textColor = appUIColor
        }

ИЛИ Создайте собственный класс UILabel (метод подкласса) и привяжите к нему необходимые метки.

import Foundation
import UIKit

class CustomFontLabel: UILabel {
    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        backgroundColor = ParentViewController().appUIColor
        font = ParentViewController().appFont
        textColor = UIColor.blackColor()
    }
}

Примечание. Шрифт и цвет, указанные в Parent VC, реализованы в CustomFontLabel. Преимущество состоит в том, что мы можем изменить свойства uilabel/любого вида все вместе в некоторых простых изменениях в Parent VC.

2) 'для' циклизации UIView для подменю. Он работает только на конкретном VC.

    override func viewWillLayoutSubviews() {
            for view in self.view.subviews  {
                if view.isKindOfClass(UITextField) {
                UITextField.appearance().font =  UIFont(name: "Copperplate", size: 20)
                }
                if view.isKindOfClass(UILabel) {
                    UILabel.appearance().font =  UIFont(name: "Copperplate", size: 20)    
                }               
            }       
        }
0
ответ дан 30 янв. '16 в 9:47
источник