Tüm iOS uygulaması için varsayılan bir yazı tipi mi ayarladınız?


155

Uygulamamda, etiketlerde, metin görünümlerinde vb. Görüntülenen her şey için kullanmak istediğim özel bir yazı tipim var.

Tüm uygulama için varsayılan yazı tipini (varsayılan olarak etiketler SystemFont kullanın) ayarlamanın bir yolu var mı?


7
Bu acıya kitlesel baktım. Dürüst olmak gerekirse, yapılacak en basit şeyin her kontrol için sadece (önemsiz) yeni bir sınıf yapmak olduğunu gördük. UIButton için SJButton yapın. Hem initWithFrame hem de initWithCode öğelerini geçersiz kılmayı unutmayın. Her kontrol için (örneğin UIButton, vb.) Renkleri veya istediğinizi ayarlayın. Dikkatle pick int boyutunu (yani bu STORYBOARD SET SET boyutu olacak) ve sonra (tercih ettiğiniz gibi) bu boyutu kullanın (ve diyelim ki, yazı tipi, renk - ne olursa olsun). Sadece birkaç satır kod, inanılmaz derecede düzenli ve uzun vadede size büyük zaman kazandırır.
Fattie

@JoeBlow Bulgularınızı gönderdiğiniz için teşekkürler - kendime cevap vermek için zaman harcamak üzereydim
jj.

@ jj- Doğru. IBDesignableBu günlerde kesinlikle kullanmanız GEREKİR . Umarım yardımcı olur. Ayrıca bu ilginç KG'yi düşünün: stackoverflow.com/a/38000466/294884
Fattie

Yanıtlar:


158

İOS 5'te UIApearance proxy'sini kullanarak mümkün görünüyor.

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

Bu, yazı tipini uygulamanızdaki tüm UILabel'ler için özel yazı tipiniz olacak şekilde ayarlar. Her kontrol (UIButton, UILabel, vb.) İçin tekrarlamanız gerekir.

UIAppFonts değerini info.plist'inize koymanız ve dahil ettiğiniz yazı tipinin adını eklemeniz gerektiğini unutmayın.


46
Yanıtınız için teşekkürler. Bunu çalıştırabildim. Yazı tipi boyutunu belirlemeden yazı tipini belirtmenin bir yolu olup olmadığını biliyor musunuz? Uygulamamda, aynı yazı tipi boyutunu paylaşmayan etiketler var.
Brandon

23
Bunu her örneğin nokta boyutunu geçersiz kılmadan yapabilir miyim?
Michael Forrest

17
setFont:yöntemi kullanımdan kaldırıldı
Anand

12
@ Ve bundan emin misin? Şu anda kullanımdan kaldırılmış olarak işaretlendiğini görmüyorum UILabel. Bu için kullanımdan kaldırıldı UIButtonancak yazı tipini kullanarak titleLabelbir olduğunu property yerine UILabelyani sadece için görünüm proxy ile yazı tipini ayarlayarak, UILabelince olmalıdır.
Adrian Schönig

6
@Ve UILabel için kullanılmıyor.
Alastair Stuart

118

Hızlı 5

Fábio Oliveira'nın cevabına dayanarak ( https://stackoverflow.com/a/23042694/2082851 ), kendi hızlılığımı yapıyorum 4.

Kısacası, bu uzantı borsaları varsayılan fonksiyonları init(coder:), systemFont(ofSize:), boldSystemFont(ofSize:), italicSystemFont(ofSize:)benim özel yöntemlerle.

Tam olarak uygulanmadığını, ancak uygulamamı temel alarak daha fazla yöntem alışverişi yapabileceğinizi unutmayın.

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
en iyi cevap!! sistem yazı tipini otomatik olarak geçersiz kılar, parlak
Kappe

2
Birisi "NSCTFontUIUsageAttribute" satırıyla ilgili problemleri varsa: if let fontAttribute = fontDescriptor.fontAttributes[.nsctFontUIUsage] as? String {benim için hile yaptı.
Bilgi

1
UILabelmetin stilini (kalın, başlık, başlık vb.) ayarlayan s ile çalışmıyor gibi görünüyor ... yalnızca belirli bir boyuta ve sistem yazı tipi kümesine sahip yazı tipiyle çalışır. @ nahung89
aviran

1
Bu aynı zamanda bazı sistem UI yazı tiplerini de değiştirir. Örneğin, klavye öneri listesi ve eylem sayfası. Bunun Apple'ın uygulamayı reddetmesine neden olup olmayacağını bilmiyorum
Henry H Miao

1
Bu cevabın yayınlanmasından bu yana bir yıl geçti. Herkes bunu başarmak için daha "yerli" bir Apple yolu var mı?
Greg Hilston

75

SystemFont'u geçersiz kılmak için başka bir çözüm daha var.

Sadece bir kategori oluşturun

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

Bu, varsayılan uygulamanın yerini alacak ve çoğu UIControl sistemi systemFont'u kullanacaktır.


1
Bu elma kılavuzları dahilinde mi?
Rambatino

Bu daha çok bir hack. Herhangi bir özel yöntem kullanmadığı için bu hack ile uygulama kaydımı eklemedim. Daha sağlam bir çözüm istiyorsanız, bunu da kontrol etmenizi öneririm: github.com/0xced/FontReplacer
Hugues BR

2
Bu iyi. Apple belgelenmemiş işlevleri kullanmanızı istemiyor. Herkese açık olan yöntemleri "girmenize" izin verilir.
mxcl

4
Bir kategoride sınıfla aynı imzayı taşıyan yöntemler varsa, davranışı genişletir tanımsız olur. Sınıf yöntemlerini değiştirmek için yöntem swizzling'i kullanmalısınız (bu da iyi bir fikir değildir).
GreatWiz

1
Diğerlerinin de belirttiği gibi, bu çözüm, çoğu zaman etkili olması muhtemel olmakla birlikte, teknik olarak tanımlanmamış davranış potansiyeli getirmektedir. Eğer risk almak istemiyorsanız, yöntem swizzling daha iyi bir seçenek olabilir. Bu sorunun cevabı swizzling ile aynı çözümü sunuyor: stackoverflow.com/questions/19542942/…
Nathan Hosselton

64

Swift kullanıyorsanız, bir UILabel uzantısı oluşturabilirsiniz:

extension UILabel {

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

}

Ve sonra görünüm proxy'nizi yaptığınız yer:

UILabel.appearance().substituteFontName = applicationFont

Adlı UI_APPEARANCE_SELECTORbir özellik üzerinde kullanılan eşdeğer Objective-C kodu vardır substituteFontName.

İlave

Kalın ve normal yazı tiplerini ayrı ayrı ayarlamak istediğiniz durumda:

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

Sonra UIAgörünüm proxy'leriniz için:

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

Not: kalın değiştirmenin işe yaramadığını fark ederseniz, varsayılan yazı tipi adının "Orta" içermemesi mümkündür. Gerektiği gibi başka bir maç için bu dizeyi değiştirin (aşağıdaki yorumlarda Mason sayesinde).


Bulduğum bir dezavantajı, UIAlertController ile uyarıları başlattığımda, .Cancel stiline sahip düğmenin .Default stiline sahip düğmeyle aynı olması (en azından GillSans kullanırken). Normalde .Cancel normal ağırlık yazı tipi ve .Default kalın olacaktır. Herhangi bir fikir?
Mason G. Zhwiti

Üzgünüm, demek istediğim .İptal etiketleri normalde kalın ve Varsayılan normalde normal ağırlık olacaktır.
Mason G. Zhwiti

2
@ MasonG.Zhwiti Bu durumda, UILabeluzantıyı kalın harflerle ek yazı tipi adı alacak şekilde ayarlamıştım . Ardından, set"Kalın" öğesinin yazı tipi adında olup olmadığını kontrol edin ve bir durumda seti yok sayın ve diğerinde kullanın. Bir örnek düzenleyeceğim ve ekleyeceğim.
Sandy Chapman

@SandyChapman Teşekkürler! Bu yeni tekniği deniyorum ve bu mantıklı, ama benim için çalışmıyor gibi görünüyor. İOS 8.3 simülatöründe GillSans ve GillSans-Bold kullanıyorum. Bu tekniği test ettiniz mi?
Mason G.Zhwiti

2
@SandyChapman Neler olduğunu anladım. İOS 8 için varsayılan yazı tipleri HelveticaNeueInterface-Regular veya (kalın) HelveticaNeueInterface-MediumP4 olma eğilimindedir. Yani "Kalın" aramak hiçbir şeyle eşleşmiyordu. Ben olarak değiştirdim rangeOfString("Medium")ve işe yaradı.
Mason G.Zhwiti

23

Hugues BR cevap geliştirerek ancak yöntem swizzling kullanarak başarıyla tüm yazı tipleri benim app istenen yazı tipine değiştiren bir çözüm geldi.

Dinamik Tip ile ilgili bir yaklaşım iOS 7'de aradığınız şey olmalıdır. Aşağıdaki çözüm Dinamik Tip kullanmıyor.


Notlar:

  • aşağıdaki kod, sunulduğu haliyle asla Apple'ın onayına sunulmamıştır;
  • Apple gönderimini geçen, - initWithCoder:geçersiz kılma olmadan daha kısa bir sürümü var . Ancak bu tüm davaları kapsamaz;
  • aşağıdaki kod, AppDelegate sınıfımın içerdiği ve böylece her yerde ve tüm UIFont örneklerinde kullanılabilen uygulamamın stilini ayarlamak için kullandığım bir sınıfta bulunur;
  • Zapfino'yu burada sadece değişiklikleri daha görünür kılmak için kullanıyorum;
  • bu kodda bulabileceğiniz herhangi bir gelişme memnuniyetle karşılanmaktadır.

Bu çözüm, nihai sonucu elde etmek için iki farklı yöntem kullanır. Birincisi, UIFont sınıf yöntemlerini geçersiz kılıyor + systemFontWithSize:ve alternatiflerimi kullananlara benziyor (burada, değiştirmenin başarılı olduğundan şüphe duymak için "Zapfino" kullanıyorum).

Diğer yöntem, alternatiflerimin - initWithCoder:herhangi bir oluşumunu CTFontRegularUsageve benzerini değiştirmek için UIFont'taki yöntemi geçersiz kılmaktır . Bu son yöntem gerekliydi çünkü UILabelNIB dosyalarında kodlanan nesnelerin + systemFontWithSize:sistem yazı tiplerini alma yöntemlerini kontrol etmediklerini ve bunun yerine nesne olarak kodlandıklarını gördüm UICTFontDescriptor. Geçersiz kılmaya çalıştım - awakeAfterUsingCoder:ama bir şekilde film şeridimdeki her kodlanmış nesne için çağrılıyordu ve çökmelere neden oluyordu. Geçersiz - awakeFromNibkılmak NSCodernesneyi okumama izin vermez .

#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

Bu uygulamayı UIFont'a sahip olmayan iOS6'da nasıl kullanıyorsunuzDescriptor
Utku Yıldırım

Sağlanan yazı tipinin kalın veya italik olup olmadığını kontrol etmek ve kendi varyasyonlarım ile değiştirmek için "UIFontTraits" kod çözücü anahtarını kullandım. Bu gist buradan aldım gist.github.com/Daij-Djan/5046612 .
Fábio Oliveira

Cevabınız için şimdiden başka bir çözüm kullandım. Tekrar ihtiyacım olduğunda kontrol edeceğim :)
Utku Yıldırım

2
Teşekkürler FábioOliveira, bir cazibe gibi çalışıyor! Başlığa #import <objc / runtime.h> koymanız gereken bir şey daha, aksi takdirde 'Yöntem' sınıfını (XCode 6'da aldığım hata) kullanarak hata alırsınız
nahung89

Bazı nedenlerden dolayı, iOS 8'de modals ( UIAlertController) yazı tipini değiştirmez.
Randomblue

13

Sandy Chapman'ın cevabını tamamlamak için , Objective-C'deki bir çözüm (bu kategoriyi değiştirmek istediğiniz yere koyun UILabel Appearance):

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

Arayüz dosyası, bu yöntemin, uygulama temsilciniz gibi yerlerden daha sonra kullanılmak üzere herkese açık olarak bildirilmesini sağlamalıdır:

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

Ardından, Appearanceile değiştirebilirsiniz :

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

1
Merhaba, "her yerde", bu kodun her görünüm denetleyicisine eklenmesi ve yazı tipini değiştirmek istediğiniz denetleyicide kullanılan her UILabel'ın kullanılmasını mı kastediyorsunuz?
Jules

Hayır, bu kodu projenizin herhangi bir yerine bir kez koymalısınız ; sizin de AppDelegate mesela.
Damien Debin

1
@DamienDebin Kalın yazı tipi için kalın yazı tipi kullanmak istiyorum, ancak bu yazı kalın olarak değişiyor. Bir yolu var mı?
Zeeshan

Aslında işe yarıyor, Ama "Kategori" veya "Uzantı" olmalı mı? Fark burada açıklandı: stackoverflow.com/questions/7136124/…
Darius Miliauskas

4

SWIFT 3.0 VE SWIFT UYARI YORUMLARI

Uyarı mesajını şu şekilde kaldırabilirsiniz:

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

Şununla değiştirerek:

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

Lol. Swift'in bunu kullanmasına izin verdiğini bilmiyordum. Btw, yukarıdaki cevaba güncelleyeceğim. Teşekkürler @ucotta!
nahung89

4

Swift 5 için

Yukarıdaki tüm cevaplar doğru ama cihaz boyutuna göre biraz farklı bir şekilde yaptım . Burada, ATFontManager sınıfında, sınıfın üst kısmında defaultFontSize olarak tanımlanan varsayılan yazı tipi boyutunu yaptım , bu iphone plus'ın yazı tipi boyutu ve ihtiyacınıza göre değiştirilebilir.

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

Belirli bir font adı ekledim, daha fazlası için font adını ve türünü buraya yazabilirsiniz.

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

Bu sınıf, aygıta göre uygun yazı tipi boyutunu sağlamak için aygıt algılayıcısına karşılık gelir.

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

Nasıl kullanılır. Umarım yardımcı olur.

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

Bu çözümlerin hiçbiri uygulama genelinde evrensel olarak çalışmaz. Xcode'taki yazı tiplerini yönetmeye yardımcı olduğum bir şey, Storyboard'u Kaynak kodu olarak açmak (Dosya Gezgini'nde ">" Aç ">" Kaynak "olarak film şeridini Control tuşunu basılı tutarak tıklatın) ve ardından bul ve değiştir işlemidir.


3

Yazı tipi her zaman kod ve uç / film şeridi olarak ayarlanır.

Kod için, tıpkı Hugues BR'nin dediği gibi , bunu katagoride yapın sorunu çözebilir.

Uç / film şeridi için, yazı tipini değiştirmek için Uyanık Yönü uyandırabiliriz.

Bilmeni varsayalım Yönleri .Bu Yöntem Swizzling dayalı AOP programlama için bir kütüphane bulunuyor. Uygulamak için UILabel, UIButton, UITextView için bir algoritma oluşturuyoruz.

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

Hepsi bu, HelveticaNeue-light'ı yazı tipi adınızla bir makroya dönüştürebilirsiniz.


3

Birkaç yayını inceledikten sonra Swift 4 için kendi tipografi dönüşümümü oluşturdum , aşağıdaki gibi vakaların çoğunu kapsıyor:

1. Proje altyapısına ve .plist dosyasına (aynı ada sahip) yazı tipleri ekleyin:

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

Sonra

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

Son olarak bir Appdelegatesonraki aşamada oluşturulan yönteme çağrı yapın :

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

        UIFont.overrideDefaultTypography()
        return true
    }
}

@sheshnath bize daha fazla kilitlenme bilgisi verebilir misiniz?
Javier Amor Penas

1
üzgünüm hata benim tarafımdan, yazı tipi
info.plist'de

@midhunp Sizin için işe yaramaması için daha açık olabilir misiniz? Cesur yazı tipi ile benim için iyi çalışıyor.
Javier Amor Penas

2

Muhtemelen hayır, muhtemelen yazı tipini kontrolünüzde ayarlayacaksınız, ancak yazı tipi türlerini nereden alacağınızı merkezileştirerek işlemi kolaylaştırabilirsiniz, örneğin uygulama temsilcisine veya başka bir ortak sınıfın yazı tipini ve yazı tipini ayarlamanız gereken herhangi bir şey bu yöntemi çağırabilir, bu da yazı tipinizi değiştirmeniz gerektiğinde yardımcı olur, yazı tiplerini ayarladığınız her yerde yerine tek bir yerde değiştirirsiniz ... Başka bir alternatif de yazı tipini otomatik olarak ayarlayacak UI Öğeleriniz, ancak bu aşırı olabilir.


kayıt için, ben yaptım, ama @Randall temsilcisi gerekiyordu ve iyi bir cevap verdi. Sadece
5.0'dan

4
Yaptıklarına katılmıyorum. Seçtiğiniz cevap, sorunuz iphone-sdk-4.0 olarak etiketlendiğinde geçerli değil.
Paulo Casaretto

@Sam Jarman, Randall'ın aşağıdaki cevabı doğru - gelecekteki ziyaretçiler için bu şekilde işaretleyebilir misiniz?
Bill

1

NUI , UIApearance proxy'sine bir alternatiftir. Birden fazla uygulamada yeniden kullanılabilen bir stil sayfasını değiştirerek, uygulamanız boyunca çok sayıda UI öğesi türünün yazı tipi (ve diğer birçok özellik) üzerinde kontrol sağlar.

NUILabelEtiketlerinize bir sınıf ekledikten sonra , stil sayfalarında yazı tiplerini kolayca kontrol edebilirsiniz:

LabelFontName    String    Helvetica

Farklı yazı tipi boyutlarına sahip etiketleriniz varsa, boyutlarını NUI'nin Label, LargeLabel ve SmallLabel sınıflarını kullanarak kontrol edebilir veya hatta kendi sınıflarınızı hızlı bir şekilde oluşturabilirsiniz.


1

Hızlı yazı tipi bu tür gibi kullanıyorum. Yazı tipi uzantısı sınıfını kullanma.

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'in FinishedLaunching()koymak kodu içindeki Xamarin.iOS için şöyle : -

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

Tüm uygulama için yazı tipi ayarlayın ve UIAppFontsInfo.plist'de ' ' tuşu ekleyin , yol yazı tipi dosyanızın .ttf dosyasının bulunduğu yol olmalıdır. Benim için projemdeki 'fonts' klasörünün içindeydi.

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

0

@Randall belirttiğimiz gibi iOS 5.0+ UIApperancevekil sınıf tüm örneklerini görünümünü özelleştirmek için kullanılabilir devamı .

Xcodes otomatik tamamlama, kullanılabilir özelliklerin tümünü göstermez ve bir hata atabilir, ancak yazabilirsiniz ve derleyecektir.

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

-1

Aynı şeyi Swift -Xcode 7.2'de Ebeveyn Görüntüleme Denetleyicisi ve Çocuk görüntüleme denetleyicisi (Devralma) kullanarak da başardık.

Dosya - Yeni - Cocoa Touch sınıfı - 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)
        }
    }    

Alt görünüm denetleyicileri yapın ve bir StoryBoard VC ile ilişkilendirin, bir textLabel ekleyin.

    import UIKit

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

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

VEYA Özel bir UILabel Sınıfı (Alt sınıflandırma yöntemi) oluşturun ve gerekli etiketleri onunla ilişkilendirin.

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

Not: Üst VC'de bildirilen Font ve renk CustomFontLabel'da uygulanır. Avantajı, Veli VC'deki bazı basit değişikliklerde uilabel / herhangi bir görünümün özelliklerini birlikte değiştirebilmemizdir.

2) alt görünümler için UIView döngüsü için 'for'. Sadece belirli bir VC'de çalışır.

    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)    
                }               
            }       
        }
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.