पूरे iOS ऐप के लिए एक डिफ़ॉल्ट फ़ॉन्ट सेट करें?


155

मेरे पास एक कस्टम फॉन्ट है जिसे मैं अपने ऐप में टेक्स्ट प्रदर्शित करने के लिए उपयोग करना चाहता हूं, लेबल, टेक्स्ट व्यू आदि।

क्या पूरे ऐप के लिए डिफ़ॉल्ट फ़ॉन्ट (डिफ़ॉल्ट रूप से लेबल सिस्टमफ़ोंट द्वारा लेबल) सेट करने का एक तरीका है?


7
व्यापक रूप से इस शोक को देखा। हमने ईमानदारी से पाया है कि प्रत्येक नियंत्रण के लिए एक सरल (तुच्छ) नई कक्षा बनाना है। तो UIButton के लिए, SJButton बनाएं। InitWithFrame और initWithCode दोनों को ओवरराइड करना न भूलें। प्रत्येक नियंत्रण के लिए (UIButton, आदि का कहना है) रंगों को सेट करें या आपको जो भी पसंद हो। Int code में साइज़ (यानी वह साइज़ ON THE STORYBOARD) होगा, और तब (जैसा आप चाहें) उस साइज़ (और सेट, फॉन्ट, कलर - जो भी हो) का इस्तेमाल करें। यह कोड की केवल कुछ पंक्तियाँ है, अविश्वसनीय रूप से सुव्यवस्थित है, और आपको लंबे समय में विशाल समय बचाता है।
फेटी

@JoeBlow अपने निष्कर्षों को पोस्ट करने के लिए धन्यवाद - जवाब देने के लिए समय बिताने के बारे में था कि खुद को
jj।

@ जज- सही है। भूलकर भी आप IBDesignableइन दिनों का उपयोग न करें । आशा करता हूँ की ये काम करेगा। इस दिलचस्प क्यूए पर भी विचार करें: stackoverflow.com/a/38000466/294884
Fattie

जवाबों:


158

यह UIAppearance प्रॉक्सी का उपयोग करके iOS 5 में संभव प्रतीत होता है।

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

वह फ़ॉन्ट सेट करेगा जो आपके ऐप में सभी UILabels के लिए आपका कस्टम फ़ॉन्ट है। आपको इसे प्रत्येक नियंत्रण (UIButton, UILabel, आदि) के लिए दोहराना होगा।

याद रखें कि आपको अपनी जानकारी में UIAppFonts वैल्यू डालना होगा। आप जिस फ़ॉन्ट को शामिल कर रहे हैं उसका नाम शामिल करें।


46
जवाब देने के लिए धन्यवाद। मैं यह काम करने में सक्षम था। क्या आप जानते हैं कि फ़ॉन्ट आकार निर्दिष्ट किए बिना फ़ॉन्ट निर्दिष्ट करने का कोई तरीका है? मेरे ऐप में मेरे लेबल हैं जो समान फ़ॉन्ट आकार साझा नहीं करते हैं।
ब्रैंडन

23
क्या मैं हर उदाहरण के बिंदु आकार को देखे बिना ऐसा कर सकता हूं?
माइकल फॉरेस्ट

17
setFont:विधि पदावनत किया जाता है
आनंद 10

12
@ और क्या आप इस बारे में निश्चित हैं? मुझे यह नहीं दिख रहा है क्योंकि इसमें पदावनत किया गया है UILabel। इसके लिए पदावनत किया जाता है, UIButtonलेकिन यह titleLabelसंपत्ति के बजाय फ़ॉन्ट का उपयोग करता है UILabel, जो कि ए है , इसलिए केवल इसके लिए उपस्थिति प्रॉक्सी के साथ फ़ॉन्ट सेट UILabelकरना ठीक होना चाहिए।
एड्रियन शॉनिग

6
@ और यह UILabel के लिए पदावनत नहीं है।
एलेस्टेयर स्टुअर्ट

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कि सेट-शैली (बोल्ड, शीर्षक, शीर्षक, आदि) के साथ काम करने के लिए नहीं लगता है ... केवल उस फ़ॉन्ट के साथ काम करता है जिसमें एक विशिष्ट आकार और सिस्टम फ़ॉन्ट सेट होता है। @ nahung89
aviran

1
यह कुछ सिस्टम UI फोंट को भी स्विच करता है। उदाहरण के लिए, कीबोर्ड सुझाव सूची और एक्शन शीट। नहीं पता कि क्या इससे ऐप्पल को अस्वीकार कर दिया जाएगा
हेनरी एच मियाओ

1
इस जवाब को पोस्ट किए एक साल हो गया है। क्या किसी के पास इसे प्राप्त करने के लिए अधिक "देशी" Apple तरीका है?
ग्रेग हिल्स्टन

75

वहाँ भी एक और समाधान है जो सिस्टम को ओवरराइड करने के लिए होगा।

बस एक श्रेणी बनाएं

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
क्या यह सेब के दिशा निर्देशों के भीतर है?
रामबेटिनो

यह ज्यादा हैक है। मैंने इस हैक के साथ अपना ऐप रजिस्टर नहीं जोड़ा है, क्योंकि यह किसी भी निजी तरीके का उपयोग नहीं कर रहा है। यदि आप अधिक मजबूत समाधान चाहते हैं, तो मैं आपको यह जांचने के लिए भी सुझाव देता हूं: github.com/0xced/FontReplacer
Hugues BR

2
यह ठीक है। Apple बस आपको अनिर्दिष्ट कार्यों का उपयोग नहीं करना चाहता। आपको सार्वजनिक रूप से "स्विज़ल" विधियों की अनुमति है।
mxcl 20

4
जब किसी श्रेणी में उसी हस्ताक्षर के साथ विधियां होती हैं जिस वर्ग के व्यवहार को विस्तारित करना अपरिभाषित होता है। कक्षा के तरीकों को बदलने के लिए आपको विधि स्विज़लिंग का उपयोग करना चाहिए (जो कि एक अच्छा विचार नहीं है)।
ग्रेटविज़

1
जैसा कि अन्य ने बताया है, यह समाधान, जबकि अधिकांश समय प्रभावी होने की संभावना है, तकनीकी रूप से अपरिभाषित व्यवहार की क्षमता का परिचय दे रहा है। यदि आप इसे जोखिम में डालने की तरह महसूस नहीं करते हैं, तो विधि स्विज़लिंग एक बेहतर विकल्प हो सकता है। यहां उत्तर स्वैज़लिंग के माध्यम से एक ही समाधान प्रदान करता है: stackoverflow.com/questions/19542942/…
नाथन हॉसल्टन

63

यदि आप स्विफ्ट का उपयोग कर रहे हैं, तो आप एक 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नाम के साथ एक संपत्ति पर उपयोग करने के लिए समान उद्देश्य-सी कोड है 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

नोट: यदि आप पा रहे हैं कि बोल्ड प्रतिस्थापन काम नहीं कर रहा है, तो संभव है कि डिफ़ॉल्ट फ़ॉन्ट नाम में "माध्यम" न हो। आवश्यकतानुसार एक और मैच के लिए उस स्ट्रिंग को स्विच करें (नीचे टिप्पणी में मेसन के लिए धन्यवाद)।


इसका एक नकारात्मक पहलू यह है कि मैंने पाया है कि जब मैं UIAlertController के साथ अलर्ट शुरू करता हूं, तो .Cancel स्टाइल वाला बटन .Default स्टाइल (कम से कम जब GillSans का उपयोग करते हुए) बटन के साथ होता है। जबकि सामान्य तौर पर। कैन्सेल एक नियमित वज़न फ़ॉन्ट होगा, और .Default बोल्ड होगा। कोई विचार?
मेसन जी। ज़्विती

क्षमा करें, मेरा मतलब था। कैनसेल लेबल सामान्य रूप से बोल्ड होगा, और डिफ़ॉल्ट रूप से सामान्य रूप से नियमित वजन होगा।
मेसन जी। ज़्विती

2
@ MasonG.Zhwiti उस मामले में, मैं निश्चित रूप से UILabelबोल्ड के लिए एक अतिरिक्त फ़ॉन्ट नाम लेने के लिए एक्सटेंशन सेट करूँगा । फिर setएक चेक में यह देखने के लिए कि क्या "बोल्ड" फ़ॉन्ट नाम में है और एक मामले में सेट को अनदेखा करें, और इसे दूसरे में उपयोग करें। मैं एक उदाहरण जोड़ूंगा।
सैंडी चैपमैन

@SandyChapman धन्यवाद! मैं इस नई तकनीक की कोशिश कर रहा हूं, और यह समझ में आता है, लेकिन यह मेरे लिए काम नहीं करता है। मैं iOS 8.3 सिम्युलेटर पर GillSans और GillSans-Bold का उपयोग कर रहा हूं। क्या आपने इस तकनीक का परीक्षण किया है?
मेसन जी। ज़्विती

2
@ कैंडीचंपमैन मुझे पता चला कि क्या चल रहा है। IOS 8 के लिए डिफ़ॉल्ट फोंट HelveticaNeueInterface-Regular या (बोल्ड के लिए) HelveticaNeueInterface-MediumP4 हैं। इसलिए "बोल्ड" की तलाश कभी भी कुछ मेल नहीं खा रही थी। मैंने इसे बदल दिया rangeOfString("Medium")और यह काम कर गया।
मेसन जी। ज़्विती

23

हग्स बीआर उत्तर से विकसित हो रहा है, लेकिन विधि स्विज़लिंग का उपयोग करके मैं एक ऐसे समाधान पर पहुंच गया हूं जो मेरे ऐप में सभी फ़ॉन्ट को वांछित फ़ॉन्ट में सफलतापूर्वक बदल रहा है।

डायनेमिक प्रकार के साथ एक दृष्टिकोण होना चाहिए कि आपको iOS 7 पर क्या देखना चाहिए। निम्नलिखित समाधान डायनामिक प्रकार का उपयोग नहीं कर रहा है।


टिप्पणियाँ:

  • नीचे दिए गए कोड, इसकी प्रस्तुत स्थिति में, कभी भी Apple अनुमोदन के लिए प्रस्तुत नहीं किया गया था;
  • इसका एक छोटा संस्करण है जो Apple सबमिशन को पास करता है, जो कि - initWithCoder:ओवरराइड के बिना है । हालाँकि यह सभी मामलों को कवर नहीं करेगा;
  • निम्नलिखित कोड एक ऐसी कक्षा में मौजूद है जिसका उपयोग मैं अपने ऐप की शैली को सेट करने के लिए करता हूं, जो कि मेरे AppDelegate वर्ग द्वारा शामिल है और इस प्रकार हर जगह और सभी यूआईएफओटी उदाहरणों के लिए उपलब्ध है;
  • मैं यहाँ केवल अधिक परिवर्तन दिखने के लिए Zapfino का उपयोग कर रहा हूँ;
  • इस कोड में आपको जो भी सुधार मिल सकता है, वह स्वागत योग्य है।

यह समाधान अंतिम परिणाम प्राप्त करने के लिए दो अलग-अलग तरीकों का उपयोग करता है। पहला UIFont वर्ग विधियों + systemFontWithSize:और उन लोगों के साथ समान है जो मेरे विकल्पों का उपयोग करते हैं (यहां मैं "Zapfino" का उपयोग करता हूं ताकि कोई संदेह न रह जाए कि प्रतिस्थापन सफल था)।

अन्य विधि - initWithCoder:UIFont पर विधि को ओवरराइड करने के लिए है CTFontRegularUsageऔर मेरे विकल्पों द्वारा किसी भी तरह की घटना को प्रतिस्थापित करने के लिए । यह अंतिम विधि आवश्यक थी क्योंकि मैंने पाया है कि UILabelएनआईबी फ़ाइलों में एन्कोडेड ऑब्जेक्ट + 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

आप iOS6 पर इस कार्यान्वयन का उपयोग कैसे करते हैं, जिसमें UIFontDescriptor नहीं है
Utku Yıldırım

मैंने डिकोडर कुंजी "UIFontTraits" का उपयोग किया है यह जांचने के लिए कि क्या प्रदान किया गया फ़ॉन्ट बोल्ड या इटैलिक है और इसे अपनी भिन्नताओं के साथ बदलें। इस सार यहाँ से समझ गया gist.github.com/Daij-Djan/5046612
फाबियो ओलिवेरा

उत्तर के लिए धन्यवाद मैंने अभी के लिए एक और समाधान का उपयोग किया। मैं इसे फिर से जाँच करूँगा जब मुझे इसकी आवश्यकता होगी :)
Utku Yıldırım

2
धन्यवाद @ FábioOliveira, यह एक आकर्षण की तरह काम करता है! हेडर पर सिर्फ एक और बात जो आपको #import <objc / runtime.h> डालनी होगी, अन्यथा आपको 'मेथड' क्लास (XCode 6 में प्राप्त होने वाली त्रुटि) का उपयोग करके त्रुटि मिलेगी
nahung89

किसी कारण से, iOS 8 पर, मॉडल्स ( UIAlertController) फ़ॉन्ट नहीं बदलते हैं।
Randomblue

13

सैंडी चैपमैन के जवाब को पूरा करने के लिए , यहां उद्देश्य-सी में एक समाधान दिया गया है (इस श्रेणी को कहीं भी रखें जिसे आप बदलना चाहते हैं 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 का उपयोग किया गया है, जहां आप फ़ॉन्ट बदलना चाहते हैं?
जूल्स

नहीं, आपको इस कोड को एक बार , अपने प्रोजेक्ट में कहीं भी लगाना होगा; उदाहरण के लिए अपने appdelegate में ।
डेमियन देबिन

1
@DamienDebin मैं बोल्ड के लिए बोल्ड फ़ॉन्ट का उपयोग करना चाहता हूं लेकिन यह बोल्ड से लाइट में बदल जाता है। किसी भी तरह से चारों ओर?
जीशान

वास्तव में, यह काम करता है, लेकिन क्या यह "श्रेणी" या "विस्तार" होना चाहिए? अंतर यहां बताया गया है: stackoverflow.com/questions/7136124/…
डेरियस मिलियास्कस

4

स्विफ्ट 3.0 और स्विफ्ट वॉर्निंग के लिए टिप्पणी

आप पंक्ति में चेतावनी संदेश निकाल सकते हैं:

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

इसे बदलकर:

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

जबरदस्त हंसी। मुझे नहीं पता था कि स्विफ्ट इसका उपयोग करने की अनुमति देती है। Btw, मैं इसे उपरोक्त उत्तर के लिए अद्यतन करूंगा। शुक्रिया @ucotta!
nahung89

4

स्विफ्ट 5 के लिए

उपरोक्त सभी उत्तर सही हैं लेकिन मैंने कुछ अलग तरीके से किया है जो डिवाइस के आकार के अनुसार है । इधर, ATFontManager कक्षा में, मैं बना दिया है डिफ़ॉल्ट फ़ॉन्ट आकार के रूप में वर्ग के शीर्ष पर परिभाषित है defaultFontSize , इस का फ़ॉन्ट आकार है प्लस iphone और आप अपने आवश्यकता के अनुसार बदला जा सकता है।

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 में फोंट को प्रबंधित करने में मदद करने के लिए मिली, वह है स्टोरीबोर्ड को सोर्स कोड (फाइल्स नेवीगेटर में कंट्रोल-क्लिक स्टोरीबोर्ड> "Open as"> "Source") के रूप में खोलना, और फिर ढूंढना-बदलना।


3

फ़ॉन्ट प्रकार हमेशा कोड और नीब / स्टोरीबोर्ड में सेट किया जाना चाहिए।

कोड के लिए, जैसे ह्यूजेस बीआर ने कहा , इसे कैटागरी में करें समस्या को हल कर सकते हैं।

Nib / स्टोरीबोर्ड के लिए, हम फ़ॉन्ट प्रकार बदलने के लिए Method Swizzling awakeFromNib को विधि कर सकते हैं क्योंकि nib / स्टोरीबोर्ड से UI तत्व हमेशा स्क्रीन में दिखाने से पहले इसे कॉल करते हैं।

मुझे लगता है कि आप पहलुओं को जानते हैं । यह एओपी प्रोग्रामिंग के लिए एक पुस्तकालय है, जो विधि स्विज़लिंग के आधार पर है। हम इसे लागू करने के लिए 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

मैंने कुछ पोस्ट की समीक्षा करने के बाद स्विफ्ट 4 के लिए टाइपोग्राफी का अपना रूपांतरण बनाया , इसमें अधिकांश मामले शामिल हैं, जैसे:

1 एस्ट्रक्चर और .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
    }
}

@ शेशनाथ क्या आप हमें और दुर्घटना की जानकारी दे सकते हैं?
जेवियर अमोर पेनास

1
खेद गलती मेरी तरफ से था, फ़ॉन्ट Info.plist में सूचीबद्ध नहीं किया गया था
शेष नाथ

@midhunp क्या आप अधिक स्पष्ट हो सकते हैं ताकि यह आपके लिए काम न करे? यह बोल्ड टाइपफेस के साथ मेरे लिए अच्छा काम करता है।
जेवियर अमोर पेनास

2

शायद नहीं, आपके पास संभवतः अपने नियंत्रण पर फ़ॉन्ट सेट होगा, लेकिन आप केंद्रीयकरण द्वारा प्रक्रिया को आसान बना सकते हैं जहां आपको फ़ॉन्ट प्रकार मिलते हैं, उदाहरण के लिए ऐप प्रतिनिधि या किसी अन्य सामान्य वर्ग के पास एक विधि है जो वापस आती है फ़ॉन्ट, और फ़ॉन्ट सेट करने के लिए आवश्यक कुछ भी उस पद्धति को कॉल कर सकता है, जो आपके फ़ॉन्ट को बदलने की आवश्यकता होने पर आपकी सहायता करेगा, आप इसे फ़ॉन्ट को सेट करने के बजाय हर जगह एक स्थान पर बदल सकते हैं ... एक अन्य विकल्प उपवर्ग बनाने के लिए हो सकता है आपके UI तत्व जो स्वचालित रूप से फ़ॉन्ट सेट करेंगे, लेकिन यह ओवरकिल हो सकता है ..


रिकॉर्ड के लिए, यह वही है जो मैंने किया था, लेकिन @ रैंडल को प्रतिनिधि की आवश्यकता थी, और एक अच्छा जवाब प्रदान किया। मुझे बस 5.0 से कम का समर्थन करने की आवश्यकता है
सैम जनमन

4
आपने जो किया उससे मैं असहमत हूं। जब आपके प्रश्न का iphone-sdk-4.0 टैग किया जाता है, तो आपके द्वारा चयनित उत्तर मान्य नहीं होता है।
पाउलो कासारेटो

@ शम जरमन, नीचे रैंडल का जवाब सही है - क्या आप इसे भविष्य के आगंतुकों के लिए चिह्नित कर सकते हैं?
बिल

1

NUI , UIAppearance प्रॉक्सी का एक विकल्प है। यह आपको अपने एप्लिकेशन में बड़ी संख्या में UI तत्व प्रकारों के फ़ॉन्ट (और कई अन्य विशेषताओं) पर नियंत्रण देता है, बस एक स्टाइल शीट को संशोधित करके, जिसे कई अनुप्रयोगों में पुन: उपयोग किया जा सकता है।

NUILabelअपने लेबल में कक्षा जोड़ने के बाद , आप आसानी से स्टाइल शीट में उनके फ़ॉन्ट को नियंत्रित कर सकते हैं:

LabelFontName    String    Helvetica

यदि आपके पास विभिन्न फ़ॉन्ट आकारों के साथ लेबल हैं, तो आप NUI के लेबल, लार्जलैब और स्मॉललैब क्लासेस का उपयोग करके उनके आकारों को नियंत्रित कर सकते हैं, या जल्दी से अपनी कक्षाएं भी बना सकते हैं।


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 के FinishedLaunching()पुट कोड के अंदर Xamarin.iOS के लिए : -

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

संपूर्ण एप्लिकेशन के लिए फ़ॉन्ट सेट करें और UIAppFontsInfo.plist पर ' ' कुंजी जोड़ें , पथ वह मार्ग होना चाहिए जहां आपका फ़ॉन्ट .ttf स्थित है। मेरे लिए यह मेरी परियोजना में 'फ़ॉन्ट' फ़ोल्डर के अंदर था।

<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 में पैरेंट व्यू कंट्रोलर और चाइल्ड व्यू कंट्रोलर (इनहेरिटेंस) का उपयोग करके समान हासिल किया है।

फ़ाइल - नया - कोको टच क्लास - पेरेंटव्यूकंट्रोलर।

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

चाइल्ड व्यू कंट्रोलर बनाएं और स्टोरीबॉर्ड वीसी के साथ मिलकर एक टेक्स्टलैब जोड़ें।

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

नोट: पैरेंट वीसी में घोषित फ़ॉन्ट और रंग को CustomFontLabel में लागू किया गया है। फायदा यह है कि हम पेरेंट वीसी में कुछ साधारण बदलावों में यूलैबेल के गुणों को बदल सकते हैं।

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)    
                }               
            }       
        }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.