iOSアプリ全体のデフォルトのフォントを設定しますか?


155

アプリ、ラベル、テキストビューなどにテキストを表示するすべてに使用したいカスタムフォントがあります。

アプリ全体にデフォルトのフォント(デフォルトではラベルはSystemFontを使用)を設定する方法はありますか?


7
この悲惨さを大いに調べた。正直に言うと、最も簡単なことは、コントロールごとに(簡単な)新しいクラスを作成することです。したがって、UIButtonの場合は、SJButtonを作成します。initWithFrameとinitWithCodeの両方をオーバーライドすることを忘れないでください。各コントロール(UIButtonなど)について、色などを設定します。intコードでサイズ(つまり、ストーリーボードのSET ONのサイズになります)を注意深くピックアップし、(必要に応じて)そのサイズを使用します(フォントや色などを設定します)。それはほんの数行のコードであり、信じられないほど整頓されており、長い目で見れば膨大な時間を節約できます。
Fattie 14

@JoeBlow調査結果を投稿していただきありがとうございます。自分自身に答えるために時間を費やそうとしていました
JJ。

@ jj-そうです。忘れずに、必ず使用する必要がありますIBDesignable最近必要があります。それが役に立てば幸い。また、この興味深いQAを検討してください:stackoverflow.com/a/38000466/294884
Fattie

回答:


158

iOS 5では、UIAppearanceプロキシを使用することで可能と思われます。

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

これにより、フォントが、アプリ内のすべてのUILabelsのカスタムフォントに設定されます。コントロール(UIButton、UILabelなど)ごとに繰り返す必要があります。

UIAppFontsの値をinfo.plistに入れて、含めるフォントの名前を含める必要があることに注意してください。


46
ご回答ありがとうございます。これを機能させることができました。フォントサイズを指定せずにフォントを指定する方法があるかどうか知っていますか?アプリに同じフォントサイズを共有しないラベルがあります。
ブランドン

23
すべてのインスタンスのポイントサイズを上書きせずにこれを実行できますか?
Michael Forrest

17
setFont:メソッドは非推奨
Anand

12
@アナンド、これでよろしいですか?で非推奨とマークされていないようですUILabel。これは非推奨ですUIButtonが、titleLabel代わりにプロパティのフォントであるを使用しているUILabelため、外観プロキシでフォントを設定するだけUILabelで十分です。
AdrianSchönig2013

6
@Anand UILabelでは非推奨ではありません。
Alastair Stuart

118

スウィフト5

ファビオオリベイラの回答(https://stackoverflow.com/a/23042694/2082851)に基づいて、私は自分ですばやく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 {
    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()
    }
    ...
}

2
ベストアンサー!! 華麗なシステムフォント、自動的に上書き
Kappe

2
誰かが「NSCTFontUIUsageAttribute」行に問題がある場合:if let fontAttribute = fontDescriptor.fontAttributes[.nsctFontUIUsage] as? String {私のためにトリックを行いました。
ナレッジ、

1
UILabelテキストスタイル(太字、見出し、タイトルなど)を設定するs では機能しないようです...特定のサイズとシステムフォントが設定されているフォントでのみ機能します。@ nahung89
アビラン

1
これにより、一部のシステムUIフォントも切り替えられます。たとえば、キーボードの候補リストとアクションシート。これによりAppleがアプリを拒否するかどうかわからない
Henry H Miao

1
この回答が投稿されてから1年になります。これを達成するためのより「ネイティブな」Appleの方法を持っている人はいますか?
グレッグヒルストン、

75

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を使用します。


1
これはアップルのガイドラインの範囲内ですか?
Rambatino 2013

それはもっとハックです。このハックではアプリレジスタを追加していません。プライベートメソッドを使用していないためです。より堅牢なソリューションが必要な場合は、これも確認することをお勧めします:github.com/0xced/FontReplacer
Hugues BR

2
これで結構です。Appleは、文書化されていない関数を使用したくないだけです。公開されているメソッドを「スウィズル」することができます。
mxcl、2014

4
カテゴリがクラスと同じシグネチャを持つメソッドを持っている場合、それが拡張する動作は未定義です。クラスメソッドを置き換えるには、メソッドスウィズリングを使用する必要があります(これもお勧めできません)。
GreatWiz、2014年

1
他の人が指摘したように、このソリューションは、ほとんどの場合効果的である可能性が高いですが、技術的には未定義の動作の可能性をもたらしています。危険を冒したくない場合は、メソッドのスウィズリングが適切なオプションとなる場合があります。ここでの答えは、スウィズリングによる同じソリューションを提供します: stackoverflow.com/questions/19542942/...
ネイサンHosselton

64

Swiftを使用している場合は、UILabel拡張機能を作成できます。

extension UILabel {

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

}

そして、あなたがあなたの外観をプロキシする場所:

UILabel.appearance().substituteFontName = applicationFont

UI_APPEARANCE_SELECTORという名前のプロパティで使用する同等のObjective-CコードがありますsubstituteFontName

添加

太字と通常のフォントを別々に設定したい場合:

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

次に、UIAppearanceプロキシの場合:

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

注:太字の置換が機能しない場合は、デフォルトのフォント名に「Medium」が含まれていない可能性があります。必要に応じて、その文字列を別の一致に切り替えます(以下のコメントでMasonに感謝します)。


これの欠点の1つは、UIAlertControllerでアラートを開始したときに、.Cancelスタイルのボタンが.Defaultスタイルのボタンと同じであることです(少なくともGillSansを使用している場合)。一方、.Cancelは通常の太さのフォントで、.Defaultは太字になります。何か案は?
メイソンG.ズウィティ2015

申し訳ありませんが、.Cancelラベルは通常太字になり、Defaultは通常は通常の太さになります。
メイソンG.ズウィティ

2
@ MasonG.Zhwitiその場合、UILabelボールドに追加のフォント名を使用するように拡張機能を設定する可能性があります。次に、set「ボールド」がフォント名に含まれているかどうかを確認し、ある場合にはセットを無視し、別の場合にはそれを使用します。例を編集して追加します。
Sandy Chapman

@SandyChapmanありがとう!私はこの新しいテクニックを試しています、そしてそれは理にかなっていますが、それは私のために働いているようではありません。iOS 8.3シミュレータでGillSansとGillSans-Boldを使用しています。このテクニックをテストしましたか?
メイソンG.ズウィティ

2
@SandyChapman私は何が起こっているのかを理解しました。iOS 8のデフォルトのフォントは、HelveticaNeueInterface-Regularまたは(太字の場合)HelveticaNeueInterface-MediumP4のいずれかです。したがって、「太字」を探すことは何にも一致しませんでした。私はそれを変更してrangeOfString("Medium")、うまくいきました。
メイソンG.ズウィティ

23

Hugues BRの答えから開発しましたが、メソッドのスウィズリングを使用して、アプリですべてのフォントを目的のフォントに正常に変更するソリューションにたどり着きました。

ダイナミックタイプを使用したアプローチは、iOS 7で探す必要があります。次のソリューションはダイナミックタイプを使用していません。


ノート:

  • 以下のコードは、提示された状態では、Appleの承認を受けたことはありません。
  • Appleの提出を通過したそれの短いバージョンがあり、それは - initWithCoder:オーバーライド。ただし、これですべてのケースがカバーされるわけではありません。
  • 次のコードは、AppDelegateクラスに含まれているアプリのスタイルを設定するために使用するクラスに存在するため、どこでも、すべてのUIFontインスタンスで使用できます。
  • ここでは、変更をよりわかりやすくするためにZapfinoを使用しています。
  • このコードに改善点があれば歓迎します。

このソリューションでは、2つの異なる方法を使用して最終結果を達成します。1つ目は、UIFontクラスのメソッドをオーバーライドすることです。+ systemFontWithSize:をと、私の代替手段を使用するものと同様のものです(ここでは、「Zapfino」を使用して、置換が成功したことを疑いません)。

もう1つの方法は- 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

UIFontDescriptorを持たないiOS6でこの実装をどのように使用するか
UtkuYıldırımApr

提供されているフォントが太字または斜体であるかどうかを確認するために、デコーダーキー「UIFontTraits」を使用して、独自のバリエーションに置き換えました。ここのgist.github.com/Daij-Djan/5046612から入手してください
ファビオオリヴェイラ2014

答えてくれてありがとう今のところ別のソリューションを使用しました。私はそれが再び必要になったときにそれをチェックします:)
UtkuYıldırım2014

2
@FábioOliveiraに感謝します、それは魅力のように機能します!#import <objc / runtime.h>をヘッダーに配置するために必要なもう1つのこと、それ以外の場合は、「メソッド」クラスを使用してエラーが発生します(XCode 6でエラーが発生します)
nahung89

何らかの理由で、iOS 8では、モーダル(UIAlertController)はフォントを変更しません。
Randomblue 2015

13

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"];

1
こんにちは、「どこでも」という意味ですか?そのコードはすべてのビューコントローラーに追加し、フォントを変更したいすべてのUILabelをコントローラーで使用する必要がありますか?
Jules

いいえ、このコードプロジェクトのどこにでも1回置く必要があります。たとえば、appdelegateで。
Damien Debin

1
@DamienDebinボールドにボールドフォントを使用したいのですが、これによりボールドがライトに変わります。何か方法はありますか?
Zeeshan、2015年

実際に動作しますが、「Category」か「Extention」か 違いは、ここで説明:stackoverflow.com/questions/7136124/...
ダリウスMiliauskas

4

SWIFT 3.0とSWIFT警告に関するコメント

次の行で警告メッセージを削除できます。

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

それを次のように置き換えることで:

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

笑。Swiftがこれを使用できることを知りませんでした。ところで、上記の答えに更新します。@ucottaありがとうございます!
nahung89

4

Swift 5の場合

上記のすべての答えは正しいですが、デバイスのサイズに応じて少し異なる方法で実行しました。ここで、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)!
        }
    }
}
     

特定のフォント名を追加しました。フォント名を追加してここに入力できます。

   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

これらのソリューションはいずれも、アプリ全体で普遍的に機能しません。Xcodeでフォントの管理に役立つことがわかったのは、ストーリーボードをソースコードとして開き([ファイル]ナビゲーターで[Control]をクリックしてストーリーボードをクリックし、[名前を付けて開く]> [ソース])、検索と置換を行うことです。


3

フォントタイプは常にコードとnib / storyboardで設定されます。

コードについては、Hugues BRが言ったように、それをカテゴリで実行すると問題を解決できます。

nib / storyboardの場合、nib / storyboardのUI要素は常に画面に表示される前にそれを呼び出すため、メソッドSwizzling awakeFromNibでフォントタイプを変更できます。

アスペクトを知っていると思います。これは、メソッドスウィズリングに基づくAOPプログラミング用のライブラリです。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をフォント名を含むマクロに変更できます。


3

Swift 4用にタイポグラフィの独自の変換を作成しましたいくつかの投稿を確認した後ました。これは、次のようなほとんどのケースをカバーしています。

プロジェクトのestructureと.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>

その後

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

@sheshnathより多くのクラッシュ情報を提供できますか?
Javier Amor Penas

1
申し訳ありません間違いはフォントがInfo.plistファイルに記載されていなかった、私の側からだった
sheshナス

@midhunpより明確にして、うまく機能しないようにしてください。太字の書体でうまくいきます。
Javier Amor Penas

2

おそらくそうではありませんが、おそらく自分でコントロールにフォントを設定しますが、フォントの種類をどこから取得するかを一元化することで、プロセスを簡単にすることができます。たとえば、アプリのデリゲートや他の一般的なクラスに、フォント、およびフォントを設定する必要があるものはすべて、そのメソッドを呼び出すことができます。これは、フォントを変更する必要がある場合に役立ちます。フォントを設定するすべての場所ではなく、1か所で変更します...別の方法として、自動的にフォントを設定するUI要素ですが、やり過ぎかもしれません。


記録のために、これは私がやったことですが、@ Randallは担当者を必要とし、良い答えを提供しました。サポートする必要があるのは5.0未満
Sam Jarman、2012年

4
あなたのしたことに同意しません。質問にiphone-sdk-4.0のタグが付いている場合、選択した回答は無効です。
Paulo Casaretto 2012

@Sam Jarman、以下のRandallの答えは正しいです-将来の訪問者のためにそのようにマークできますか?
ビル・

1

NUIは、UIAppearanceプロキシの代替です。複数のアプリケーションで再利用できるスタイルシートを変更するだけで、アプリケーション全体で多数のUI要素タイプのフォント(および他の多くの属性)を制御できます。

NUILabelラベルにクラスを追加した後、スタイルシートでそれらのフォントを簡単に制御できます。

LabelFontName    String    Helvetica

異なるフォントサイズのラベルがある場合、NUIのLabel、LargeLabel、SmallLabelクラスを使用してそれらのサイズを制御するか、独自のクラスをすばやく作成することもできます。


1

このようなフォントクラスを迅速に使用しています。フォント拡張クラスを使用します。

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

AppDelegate内のXamarin.iOSのFinishedLaunching()場合、次のようなコードを配置します。

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

アプリケーション全体にフォントを設定し、UIAppFontsInfo.plist に ' 'キーを追加します。パスは、フォントファイル.ttfが置かれているパスでなければなりません。私にとっては、プロジェクトの 'fonts'フォルダー内にありました。

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

0

@RandallがiOS 5.0以降について言及したように UIApperanceプロキシは、クラスのすべてのインスタンスの外観をカスタマイズするために使用することができます続きを読みます

Xcodesのオートコンプリートでは、使用可能なすべてのプロパティが表示されず、エラーがスローされる場合がありますが、入力するだけでコンパイルできます。

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

-1

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

子ビューコントローラーを作成してStoryBoard VCに関連付け、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()
    }
}

注:親VCで宣言されているフォントと色はCustomFontLabelに実装されています。利点は、親VCのいくつかの簡単な変更でuilabel / anyビューのプロパティをすべて一緒に変更できることです。

2)サブビューの「for」ループ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)    
                }               
            }       
        }
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.