简体   繁体   English

为整个 iOS 应用设置默认字体?

[英]Set a default font for whole iOS app?

I have a custom font I want to use for everything displaying text in my app, labels, text views etc.我有一个自定义字体,我想用于在我的应用程序、标签、文本视图等中显示文本的所有内容。

Is there a way to set the default font (labels by default use SystemFont) for the whole app?有没有办法为整个应用程序设置默认字体(标签默认使用 SystemFont)?

It seems to be possible in iOS 5 using the UIAppearance proxy.在 iOS 5 中使用 UIAppearance 代理似乎是可能的。

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

That will set the font to be whatever your custom font is for all UILabels in your app.这会将字体设置为应用程序中所有 UILabel 的自定义字体。 You'll need to repeat it for each control (UIButton, UILabel, etc.).您需要为每个控件(UIButton、UILabel 等)重复此操作。

Remember you'll need to put the UIAppFonts value in your info.plist and include the name of the font you're including.请记住,您需要将 UIAppFonts 值放在 info.plist 中,并包含您要包含的字体的名称。

Swift 5斯威夫特 5

Base on Fábio Oliveira's answer ( https://stackoverflow.com/a/23042694/2082851 ), I make my own swift 4.根据法比奥奥利维拉的回答( https://stackoverflow.com/a/23042694/2082851 ),我自己制作了 swift 4。

In short, this extension exchanges default functions init(coder:) , systemFont(ofSize:) , boldSystemFont(ofSize:) , italicSystemFont(ofSize:) with my custom methods.简而言之,这个扩展与我的自定义方法交换了默认函数init(coder:)systemFont(ofSize:)boldSystemFont(ofSize:)italicSystemFont(ofSize:)

Note that it's not fully implement, but you can exchange more methods base on my implementation.请注意,它还没有完全实现,但您可以根据我的实现交换更多方法。

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 {
    static var isOverrided: Bool = false

    @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, !isOverrided else { return }

        // Avoid method swizzling run twice and revert to original initialize function
        isOverrided = true

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

There is also another solution which will be to override systemFont.还有另一种解决方案是覆盖 systemFont。

Just create a category只需创建一个类别

UIFont+SystemFontOverride.h UIFont+SystemFontOverride.h

#import <UIKit/UIKit.h>

@interface UIFont (SystemFontOverride)
@end

UIFont+SystemFontOverride.m 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

This will replace the default implementation and most UIControls use systemFont.这将替换默认实现,并且大多数 UIControl 使用 systemFont。

If you're using Swift, you can create a UILabel extension:如果你使用 Swift,你可以创建一个 UILabel 扩展:

extension UILabel {

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

}

And then where you do your appearance proxying:然后你在哪里做你的外观代理:

UILabel.appearance().substituteFontName = applicationFont

There is equivalent Objective-C code using UI_APPEARANCE_SELECTOR on a property with the name substituteFontName .有相当于使用Objective-C代码UI_APPEARANCE_SELECTOR与该名称的属性substituteFontName

Addition添加

For the case where you'd want to set bold and regular fonts separately:对于您想要分别设置粗体和常规字体的情况:

extension UILabel {

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

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

Then for your UIAppearance proxies:然后对于您的 UIAppearance 代理:

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

Note: if you're finding that the bold substitution isn't working, it's possible the default font name doesn't contain "Medium".注意:如果您发现粗体替换不起作用,则默认字体名称可能不包含“中”。 Switch out that string for another match as needed (thanks to Mason in the comments below) .根据需要切换出另一个匹配的字符串(感谢下面评论中的梅森)。

Developing from Hugues BR answer but using method swizzling I've arrived to a solution that is successfully changing all the fonts to a desired font in my app.从 Hugues BR 答案开发但使用方法 swizzling 我已经找到了一个解决方案,该解决方案成功地将我的应用程序中的所有字体更改为所需的字体。

An approach with Dynamic Type should be what you should look for on iOS 7. The following solution is not using Dynamic Type.您应该在 iOS 7 上寻找动态类型的方法。以下解决方案不使用动态类型。


Notes:笔记:

  • the code below, in its presented state, was never submitted to Apple approval;以下代码在其呈现状态下从未提交给 Apple 批准;
  • there is a shorter version of it that passed Apple submission, that is without the - initWithCoder: override.有一个通过 Apple 提交的较短版本,即没有- initWithCoder:覆盖。 However that won't cover all the cases;但是,这不会涵盖所有情况;
  • the following code is present in a class I use to set the style of my app which is included by my AppDelegate class thus being available everywhere and to all UIFont instances;以下代码出现在我用来设置应用程序样式的类中,该样式包含在我的 AppDelegate 类中,因此可以在任何地方和所有 UIFont 实例中使用;
  • I'm using Zapfino here just to make the changes much more visible;我在这里使用 Zapfino 只是为了使更改更加明显;
  • any improvement you may find to this code is welcome.欢迎您对此代码进行任何改进。

This solution uses two different methods to achieve the final result.该解决方案使用两种不同的方法来实现最终结果。 The first is override the UIFont class methods + systemFontWithSize: and similar with ones that use my alternatives (here I use "Zapfino" to leave no doubts that the replacement was successful).第一个是覆盖 UIFont 类方法+ systemFontWithSize: systemFontWithSize + systemFontWithSize:并与使用我的替代方法的方法类似(这里我使用“Zapfino”来确保替换成功)。

The other method is to override - initWithCoder: method on UIFont to replace any occurrence of CTFontRegularUsage and similar by my alternatives.另一种方法是覆盖- initWithCoder: UIFont 上的方法,用我的替代方法替换CTFontRegularUsage和类似的任何出现。 This last method was necessary because I've found that UILabel objects encoded in NIB files don't check the + systemFontWithSize: methods to get their system font and instead encode them as UICTFontDescriptor objects.最后一个方法是必要的,因为我发现在 NIB 文件中编码的UILabel对象不会检查+ systemFontWithSize:方法来获取它们的系统字体,而是将它们编码为UICTFontDescriptor对象。 I've tried to override - awakeAfterUsingCoder: but somehow it was getting called for every encoded object in my storyboard and causing crashes.我试图覆盖- awakeAfterUsingCoder:但不知何故它被我的故事板中的每个编码对象调用并导致崩溃。 Overriding - awakeFromNib wouldn't allow me to read the NSCoder object.重写- 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

To complete Sandy Chapman's answer , here is a solution in Objective-C (put this category anywhere you want to change UILabel Appearance ):要完成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

The interface file, should have this method declared publicly to be used later from places like your app delegate:接口文件应该公开声明此方法,以便稍后从您的应用程序委托等地方使用:

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

Then, you can change the Appearance with:然后,您可以使用以下命令更改Appearance

[[UILabel appearance] setSubstituteFontName:@"SourceSansPro-Light"];

I created my own conversion of typography for Swift 4 after reviewing a few posts, it covers most of the cases, such as:在查看了一些帖子后,我为Swift 4创建了自己的排版转换,它涵盖了大多数情况,例如:

1st Add fonts to project estructure and to .plist file (with the same name): 1st 将字体添加到项目结构和 .plist 文件(同名):

<key>UIAppFonts</key>
<array>
    <string>Typo-Light.ttf</string>
    <string>Typo-Regular.ttf</string>
    <string>Typo-Semibold.ttf</string>
    <string>Typo-LightItalic.ttf</string>
</array>

Then然后

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

Finally call to created method at Appdelegate like next:最后在Appdelegate调用 created 方法, Appdelegate所示:

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

        UIFont.overrideDefaultTypography()
        return true
    }
}

COMMENT FOR SWIFT 3.0 AND SWIFT WARNING对 Swift 3.0 和 Swift 警告的评论

You can remove the warning message in line:您可以在行中删除警告消息:

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

By replacing it with:通过将其替换为:

let initCoderMethod = class_getInstanceMethod(self, #selector(UIFontDescriptor.init(coder:)))

For Swift 5对于 Swift 5

All the above answers are correct but i have done in little different way that is according to device size .以上所有答案都是正确的,但我根据设备大小以略有不同的方式完成了。 Here, in ATFontManager class, i have made default font size which is define at the top of the class as defaultFontSize , this is the font size of iphone plus and you can changed according to your requirement.在这里,在 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 - 5)!
            }
            return UIFont(name: fontN, size: defaultFontSize - 5)!
            
        case .iPhone5:
            if let fontSize = iPhone7PlusFontSize{
                return UIFont(name: fontN, size: fontSize - 3)!
            }
            return UIFont(name: fontN, size: defaultFontSize - 3)!
            
        case .iPhone6AndIphone7, .iPhoneUnknownSmallSize:
            if let fontSize = iPhone7PlusFontSize{
                return UIFont(name: fontN, size: fontSize - 2)!
            }
            return UIFont(name: fontN, size: defaultFontSize - 2)!
            
        case .iPhone6PAndIPhone7P, .iPhoneUnknownBigSize:
            
            return UIFont(name: fontN, size: iPhone7PlusFontSize ?? defaultFontSize)!
        case .iPhoneX, .iPhoneXsMax:
            
            return UIFont(name: fontN, size: iPhone7PlusFontSize ?? defaultFontSize)!
          
        case .iPadMini:
            if let fontSize = iPhone7PlusFontSize{
                return UIFont(name: fontN, size: fontSize + 2)!
            }
            return UIFont(name: fontN, size: defaultFontSize + 2)!
            
        case .iPadPro10Inch:
            if let fontSize = iPhone7PlusFontSize{
                return UIFont(name: fontN, size: fontSize + 4)!
            }
            return UIFont(name: fontN, size: defaultFontSize + 4)!
            
        case .iPadPro:
            if let fontSize = iPhone7PlusFontSize{
                return UIFont(name: fontN, size: fontSize + 6)!
            }
            return UIFont(name: fontN, size: defaultFontSize + 6)!
            
        case .iPadUnknownSmallSize:
            
            return UIFont(name: fontN, size: defaultFontSize + 2)!
            
        case .iPadUnknownBigSize:
            
            return UIFont(name: fontN, size: defaultFontSize + 4)!
            
        default:
            
            return UIFont(name: fontN, size: iPhone7PlusFontSize ?? 16)!
        }
    }
}
     

I have added certain font name, for more you can add the font name and type here.我已经添加了某些字体名称,更多你可以添加字体名称并在此处键入。

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

This class refers to device detector in order to provide appropriate font size according to device.此类指的是设备检测器,以便根据设备提供适当的字体大小。

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

How to use.如何使用。 Hope it will help.希望它会有所帮助。

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

None of these solutions works universally throughout the app.这些解决方案都没有在整个应用程序中通用。 One thing I found to help manage the fonts in Xcode is opening the Storyboard as Source code (Control-click storyboard in Files navigator > "Open as" > "Source"), and then doing a find-and-replace.我发现有助于在 Xcode 中管理字体的一件事是将故事板作为源代码打开(在文件导航器中按住 Control 单击故事板>“打开为”>“源”),然后进行查找和替换。

Font type always be set in code and nib/storyboard.字体类型总是在代码和笔尖/故事板中设置。

For the code,just like Hugues BR said ,do it in catagory can solve the problem.对于代码,就像Hugues BR 所说的,在分类中做可以解决问题。

For the nib/storyboard,we can Method Swizzling awakeFromNib to change font type since UI element from nib/storyboard always call it before show in the screen.对于笔尖/故事板,我们可以使用方法 SwizzlingawakeFromNib 来更改字体类型,因为笔尖/故事板中的 UI 元素总是在屏幕显示之前调用它。

I suppose you know Aspects .It's a library for AOP programing,based on Method Swizzling.我想你知道Aspects 。它是一个基于 Method Swizzling 的 AOP 编程库。 We create catagory for UILabel,UIButton,UITextView to implement it.我们为 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: 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

That's all,you can change HelveticaNeue-light to a macro with your font name.就是这样,您可以将 HelveticaNeue-light 更改为带有您字体名称的宏。

可能不会,您可能会自己在控件上设置字体,但是您可以通过集中获取字体类型的位置来简化该过程,例如让应用程序委托或其他一些通用类具有返回字体,任何需要设置字体的都可以调用该方法,这将有助于您在需要更改字体的情况下,您可以在一个地方更改它,而不是在设置字体的任何地方进行更改...另一种选择是创建子类您的 UI 元素将自动设置字体,但这可能有点矫枉过正。

NUI is an alternative to the UIAppearance proxy. NUI是 UIAppearance 代理的替代品。 It gives you control over the font (and many other attributes) of a large number of UI element types throughout your application by simply modifying a style sheet, which can be reused across multiple applications.它使您可以通过简单地修改样式表来控制整个应用程序中大量 UI 元素类型的字体(和许多其他属性),该样式表可以在多个应用程序中重复使用。

After adding a NUILabel class to your labels, you could easily control their font in the style sheet:NUILabel类添加到标签后,您可以轻松地在样式表中控制它们的字体:

LabelFontName    String    Helvetica

If you have labels with different font sizes, you could control their sizes using NUI's Label, LargeLabel, and SmallLabel classes, or even quickly create your own classes.如果你有不同字体大小的标签,你可以使用 NUI 的 Label、LargeLabel 和 SmallLabel 类来控制它们的大小,甚至可以快速创建自己的类。

Am using like this type of font class in swift.我正在 swift 中使用这种类型的字体类。 Using font extension class.使用字体扩展类。

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

For Xamarin.iOS inside AppDelegate's FinishedLaunching() put code like this :-对于 AppDelegate 的FinishedLaunching() Xamarin.iOS,将代码如下:-

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

set font for the entire application and Add ' UIAppFonts ' key on Info.plist , the path should be the path where your font file .ttf is situated .For me it was inside 'fonts' folder in my project.为整个应用程序设置字体并在 Info.plist 上添加“ UIAppFonts ”键,路径应该是字体文件 .ttf 所在的路径。对我来说,它在我的项目中的“字体”文件夹内。

<key>UIAppFonts</key>
    <array>
        <string>fonts/Lato-Regular.ttf</string>
    </array>

正如@Randall在他的回答中提到的,iOS 5.0+ UIAppearance代理可用于自定义类的所有实例的外观阅读更多

UILabel.appearance().font = .systemFont(ofSize: 17, weight: .regular)

We have achieved the same in Swift -Xcode 7.2 using Parent View Controller and Child view controller (Inheritance).我们在 Swift -Xcode 7.2 中使用父视图控制器和子视图控制器(继承)实现了相同的效果。

File - New - Cocoa Touch class - ParentViewController.文件 - 新建 - 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)
        }
    }    

Make child view controllers and associate with a StoryBoard VC, add a textLabel.制作子视图控制器并与 StoryBoard VC 关联,添加一个 textLabel。

    import UIKit

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

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

OR Make a custom UILabel Class(Sub classing method) and associate required labels to it.或者制作一个自定义 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()
    }
}

Note: The Font and colour declared in Parent VC are implemented in CustomFontLabel .注意:Parent VC 中声明的字体和颜色在 CustomFontLabel 中实现。 The advantage is we can alter the properties of uilabel/any view all together in some simple changes in Parent VC.优点是我们可以在父 VC 中进行一些简单的更改,一起更改 uilabel/any 视图的属性。

2)'for' looping UIView for sub views. 2)'for' 循环子视图的 UIView。 It works only on a particular VC.它仅适用于特定的 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)    
                }               
            }       
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM