전체 iOS 앱에 기본 글꼴을 설정 하시겠습니까?


155

앱의 텍스트, 레이블, 텍스트보기 등을 표시하는 모든 것에 사용하려는 사용자 정의 글꼴이 있습니다.

전체 앱에 기본 글꼴 (기본적으로 레이블은 SystemFont를 사용함)을 설정하는 방법이 있습니까?


7
이 비난을 엄청나게 들여다 본다. 우리는 솔직히 가장 간단한 방법은 각 컨트롤마다 (사소한) 새로운 클래스를 만드는 것입니다. UIButton의 경우 SJButton을 만드십시오. initWithFrame과 initWithCode를 모두 재정의하는 것을 잊지 마십시오. 각 컨트롤 (예 : UIButton 등)마다 색상이나 원하는 것을 설정하십시오. 조심스럽게 int 코드에서 크기 (즉, 스토리 보드에 설정된 크기가 될 것)를 말한 다음 (원하는대로) 해당 크기 (및 글꼴, 색상 등을 설정하십시오)를 사용하십시오. 몇 줄의 코드 일뿐 아니라 매우 깔끔하며 장기적으로 막대한 시간을 절약 할 수 있습니다.
Fattie

@JoeBlow 당신의 결과를 게시 주셔서 감사합니다 - 대답은 그 자신을 찾고 시간을 할애하고 있었다
JJ.

@ jj- 맞아. IBDesignable요즘 반드시 사용해야한다는 것을 잊지 마십시오 . 도움이 되길 바랍니다. 또한이 흥미로운 QA를 고려하십시오 : stackoverflow.com/a/38000466/294884
Fattie

답변:


158

iOSAppearance 프록시를 사용하는 iOS 5에서 가능합니다.

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

그러면 글꼴이 앱의 모든 UILabels에 대한 사용자 정의 글꼴이되도록 설정됩니다. 각 컨트롤 (UIButton, UILabel 등)에 대해 반복해야합니다.

info.plist에 UIAppFonts 값을 입력하고 포함하는 글꼴 이름을 포함해야합니다.


46
답변 주셔서 감사합니다. 나는 이것을 작동시킬 수있었습니다. 글꼴 크기를 지정하지 않고 글꼴을 지정하는 방법이 있는지 알고 있습니까? 앱에 동일한 글꼴 크기를 공유하지 않는 레이블이 있습니다.
Brandon

23
모든 인스턴스의 포인트 크기를 재정의하지 않고이 작업을 수행 할 수 있습니까?
Michael Forrest

17
setFont:이 방법은 더 이상 사용되지 않습니다
Anand

12
@Anand 확실합니까? 에서 더 이상 사용되지 않는 것으로 표시되지 않습니다 UILabel. 더 이상 사용되지 UIButton않지만 titleLabel대신 속성 UILabel의 글꼴을 사용하여 모양 프록시를 사용하여 글꼴을 설정하는 UILabel것이 좋습니다.
Adrian Schönig

6
@Anand UILabel에서 더 이상 사용되지 않습니다.
Alastair Stuart

118

스위프트 5

Fábio Oliveira의 답변 ( 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 {나를 위해 속임수를 쓰 십시오.
Knowledge

1
UILabel텍스트 스타일 (굵게, 제목, 제목 등)을 설정 하는 s에서는 작동하지 않는 것 같습니다 ... 특정 크기 및 시스템 글꼴 세트가있는 글꼴에서만 작동합니다. @ nahung89
aviran

1
또한 일부 시스템 UI 글꼴을 전환합니다. 예를 들어 키보드 제안 목록 및 작업 시트입니다. 몰라이 애플이 애플 리케이션 거부하게됩니다 경우
헨리 H 미아오

1
이 답변이 게시 된 지 1 년이 지났습니다. 누구든지 이것을 달성하기 위해 더 "네이티브"Apple 방법이 있습니까?
Greg Hilston

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

이것은 기본 구현을 대체하며 대부분의 UIControl은 systemFont를 사용합니다.


1
이것이 사과 지침에 있습니까?
Rambatino

더 해킹입니다. 개인 메소드를 사용하지 않으므로이 해킹에 내 앱 등록을 추가하지 않았습니다. 보다 강력한 솔루션을 원한다면 github.com/0xced/FontReplacer
Hugues BR

2
이건 괜찮아. Apple은 문서화되지 않은 기능을 사용하기를 원하지 않습니다. 공개 된 메소드를 "스위 즐"할 수 있습니다.
mxcl

4
카테고리에 클래스와 동일한 서명을 가진 메소드가있는 경우 동작을 확장하는 것은 정의되지 않습니다. 클래스 메소드를 바꾸려면 메소드 스위 즐링을 사용해야합니다.
GreatWiz

1
다른 사람들이 지적했듯이,이 솔루션은 대부분의 경우 효과적 일 수 있지만 기술적으로 정의되지 않은 행동의 가능성을 소개합니다. 위험을 감수하고 싶지 않다면 방법 스위 즐링이 더 나은 옵션 일 수 있습니다. 여기에 대한 답변은 스위 즐링을 통해 동일한 솔루션을 제공합니다. stackoverflow.com/questions/19542942/…
Nathan Hosselton

63

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_SELECTORname 속성을 사용하는 동등한 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

참고 : 굵은 체 대체가 작동하지 않는 경우 기본 글꼴 이름에 "중간"이 포함되어 있지 않을 수 있습니다. 필요에 따라 해당 문자열을 다른 일치 항목으로 전환하십시오 (아래 의견의 Mason에게 감사드립니다).


내가 찾은 단점 중 하나는 UIAlertController로 경고를 시작할 때 .Cancel 스타일이있는 버튼은 .Default 스타일이있는 버튼과 같습니다 (적어도 GillSans를 사용하는 경우). 반면 일반적으로 .Cancel은 일반 가중치 글꼴이고 .Default는 굵게 표시됩니다. 어떤 아이디어?
메이슨 G. Zhwiti

죄송합니다. .Cancel 레이블은 일반적으로 굵게 표시되며 기본적으로 보통 무게입니다.
메이슨 G. Zhwiti

2
@ MasonG.Zhwiti이 경우 UILabel굵은 체로 추가 글꼴 이름을 사용 하도록 확장 프로그램을 설정했을 것입니다 . 그런 다음 set글꼴 이름에 "굵은 체"가 있는지 확인하고 어떤 경우에는 설정을 무시하고 다른 경우에는 사용하십시오. 예제를 편집하고 추가하겠습니다.
Sandy Chapman

@SandyChapman 감사합니다! 나는이 새로운 기술을 시도하고 있으며 의미가 있지만 나에게는 효과가없는 것 같습니다. iOS 8.3 시뮬레이터에서 GillSans 및 GillSans-Bold를 사용하고 있습니다. 이 기술을 테스트 했습니까?
메이슨 G. Zhwiti

2
@ SandyChapman 나는 무슨 일이 일어나고 있는지 알아 냈습니다. iOS 8의 기본 글꼴은 HelveticaNeueInterface-Regular 또는 (굵게 표시된) HelveticaNeueInterface-MediumP4 인 경향이 있습니다. 따라서 "굵게"를 찾는 것은 아무 것도 일치하지 않았습니다. 나는 그것을 바꾸었고 rangeOfString("Medium")효과가있었습니다.
메이슨 G. Zhwiti

23

Hugues BR 답변에서 개발했지만 방법 스위 즐링을 사용하여 모든 글꼴을 내 앱에서 원하는 글꼴로 성공적으로 변경하는 솔루션에 도달했습니다.

동적 유형을 사용하는 접근 방식은 iOS 7에서 찾아야합니다. 다음 솔루션은 동적 유형을 사용하지 않습니다.


노트:

  • 아래 코드는 제시된 상태에서 Apple의 승인을받지 못했습니다.
  • Apple 제출을 통과 한 더 짧은 버전이 - initWithCoder:있습니다. 즉, 재정의 가 없습니다 . 그러나 모든 경우를 다루지는 않습니다.
  • 다음 코드는 AppDelegate 클래스에 포함 된 내 앱의 스타일을 설정하는 데 사용하는 클래스에 있으며 모든 UIFont 인스턴스에서 사용할 수 있습니다.
  • 여기에서 Zapfino를 사용하여 변경 사항을 훨씬 더 눈에 띄게 만듭니다.
  • 이 코드에 대한 개선 사항은 언제든지 환영합니다.

이 솔루션은 두 가지 방법으로 최종 결과를 얻습니다. 첫 번째는 UIFont 클래스 메소드를 대체하고 대체 방법 + systemFontWithSize:을 사용하는 메소드 와 유사합니다 (여기서는 "Zapfino"를 사용하여 교체가 성공했는지 의심하지 않습니다).

다른 방법은 - initWithCoder:UIFont의 메서드 를 재정 CTFontRegularUsage의하여 내 대안으로 발생 하고 유사한 것을 대체하는 것입니다. 이 마지막 방법은 UILabelNIB 파일로 인코딩 된 객체 + 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에서이 구현을 사용하는 방법
Utku Yıldırım

디코더 키 "UIFontTraits"를 사용하여 제공된 글꼴이 굵은 체인지 이탤릭체인지 확인하고 내 고유 한 변형으로 대체했습니다. 이 요지에서 얻었습니다 .gist.github.com / Daij-Djan / 5046612 .
Fábio Oliveira

답변 주셔서 감사합니다. 지금 다른 솔루션을 사용했습니다. 내가 :) 다시 그것을 필요로 할 때 나는 그것을 확인합니다
Utku 디림에게

2
@ FábioOliveira에게 감사합니다, 그것은 매력처럼 작동합니다! 헤더에 #import <objc / runtime.h>을 추가해야하는 또 하나의 방법입니다. 그렇지 않으면 'Method'클래스 (XCode 6에서 발생하는 오류)를 사용하여 오류가 발생합니다.
nahung89

어떤 이유로 iOS 8에서 모달 ( UIAlertController)은 글꼴을 변경하지 않습니다.
Randomblue

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

아닙니다 . 프로젝트의 어느 곳에서나이 코드를 한 번 넣어야합니다 . 예를 들어 당신의 appdelegate 에서.
Damien Debin 2016 년

1
@DamienDebin 굵은 글꼴로 굵은 글꼴을 사용하고 싶지만 굵은 글꼴로 변경되었습니다. 어쨌든?
Zeeshan

실제로 작동하지만 "범주"또는 "확장"이어야합니까? 차이는 여기에 설명 : 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:)))

롤 나는 스위프트가 이것을 사용할 수 있다는 것을 몰랐다. Btw, 나는 위의 답변으로 업데이트 할 것입니다. 감사합니다 @ucotta!
nahung89

4

스위프트 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

글꼴 유형은 항상 코드 및 펜촉 / 스토리 보드에서 설정됩니다.

Hugues BR이 말했듯 이 코드의 경우 범주에서 수행하면 문제를 해결할 수 있습니다.

펜촉 / 스토리 보드의 경우 펜촉 / 스토리 보드의 UI 요소가 항상 화면에 표시되기 전에이를 호출하므로 글꼴 유형을 변경하기 위해 awakeFromNib를 스위블 할 수 있습니다.

나는 당신이 Aspects 를 알고 있다고 가정한다 . 그것은 Method Swizzling에 기반한 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 2014 년

1
죄송합니다. 실수로 내 편에 글꼴이 info.plist에 나열되지 않았습니다
shesh nath

@midhunp 더 효과가 없어서 작동하지 않습니까?. 굵은 글씨체로 잘 작동합니다.
Javier Amor Penas

2

아마도 그렇지 않을 것입니다. 컨트롤에 글꼴을 직접 설정했을 수도 있지만 글꼴 유형을 가져 오는 위치를 중앙 집중화하여 프로세스를 쉽게 만들 수 있습니다 (예 : 앱 대리자 또는 다른 일반 클래스에 글꼴 및 글꼴을 설정 해야하는 모든 것이 해당 메소드를 호출 할 수 있습니다. 글꼴을 변경 해야하는 경우 글꼴을 설정하는 곳이 아닌 한 곳에서 글꼴을 변경하는 데 도움이됩니다 ... 또 다른 대안은 글꼴을 자동으로 설정하지만 너무 과도 할 수있는 UI 요소


기록을 위해 이것은 내가 한 일이지만 @Randall은 담당자가 필요했으며 좋은 대답을 제공했습니다. 난 단지 5.0 미만을 지원해야합니다
Sam Jarman

4
당신이 한 일에 동의하지 않습니다. 질문에 iphone-sdk-4.0 태그가 지정되어 있으면 선택한 답변이 유효하지 않습니다.
Paulo Casaretto

Randall의 @Sam Jarman의 답변은 정확합니다. 차후 방문자에게 표시 할 수 있습니까?
Bill

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

전체 응용 프로그램의 글꼴을 설정 UIAppFonts하고 Info.plist에서 ' '키를 추가 하면 경로는 글꼴 파일 .ttf가있는 경로 여야합니다.

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

0

@Randall가 언급 한 바와 같이 아이폰 OS 5.0 UIApperance프록시는 클래스의 모든 인스턴스의 모양을 사용자 정의 할 수 있습니다 더 읽기 .

Xcodes 자동 완성에는 사용 가능한 모든 속성이 표시되지 않으며 오류가 발생할 수 있지만 입력 만하면 컴파일됩니다.

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

-1

Swift -Xcode 7.2에서도 Parent View Controller와 Child View Controller (Inheritance)를 사용하여 동일한 결과를 얻었습니다.

파일-신규-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()
    }
}

참고 : Parent VC에서 선언 된 Font 및 Color는 CustomFontLabel에서 구현됩니다. 장점은 Parent VC의 간단한 변경 사항으로 uilabel / any view의 속성을 모두 함께 변경할 수 있다는 것입니다.

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.