이번 사이드프로젝트에는 상당히 많은 걸 시도하고 노력하고 있는데요,
그 중 공유할만한 수확물을 소개하려 합니다. 오늘 소개할 것은 글꼴에 관련한 것입니다.
개발자님 마다 폰트를 다루는 방법이 다양하고 각각 다른데요, 더 좋은 방법이 있다면 알려주시면 감사하겠습니다.(__)
우선, 먼저 커스텀 폰트를 적용하는 방법을 간단하게 소개하고 진행하겠습니다!
1. 프로젝트 내에 폰트 복사하고 TargetMembership 설정하기
스포카한산즈체를 적용하고자 합니다. 토스에서 사용하는 고딕체입니다.
사용하고자 하는 폰트를 모두 클릭 후 타겟멤버십에 체크해줍니다.
2. info.plist file 수정하기
Font provided by application을 추가한 후
폰트 이름 뒤 .ttf까지 깔끔하게 추가해 줍니다. 다음과 같이 폰트를 설정해 줄 수 있게 됩니다.
(1) 스토리보드에서 폰트를 설정해주거나,
(2)
anyLabel.font = UIFont(name: "customfont", size: "17")
위 두 가지 방법으로 보통 많이 사용하는데요,
아래 방법은 시스템 폰트를 원하는 커스텀 폰트로 바꿀 수 있게 됩니다.
struct AppFontName {
static let regular = "SpoqaHanSans"
static let bold = "SpoqaHanSans-Bold"
static let italic = "SpoqaHanSans-Light"
}
extension UIFontDescriptor.AttributeName {
static let nsctFontUIUsage = UIFontDescriptor.AttributeName(rawValue: "NSCTFontUIUsageAttribute")
}
extension UIFont {
@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) {
if let fontDescriptor = aDecoder.decodeObject(forKey: "UIFontDescriptor") as? UIFontDescriptor {
if let fontAttribute = fontDescriptor.fontAttributes[.nsctFontUIUsage] as? String {
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)!
}
else {
self.init(myCoder: aDecoder)
}
}
else {
self.init(myCoder: aDecoder)
}
}
class func overrideInitialize() {
if self == UIFont.self {
let systemFontMethod = class_getClassMethod(self, #selector(systemFont(ofSize:)))
let mySystemFontMethod = class_getClassMethod(self, #selector(mySystemFont(ofSize:)))
method_exchangeImplementations(systemFontMethod!, mySystemFontMethod!)
let boldSystemFontMethod = class_getClassMethod(self, #selector(boldSystemFont(ofSize:)))
let myBoldSystemFontMethod = class_getClassMethod(self, #selector(myBoldSystemFont(ofSize:)))
method_exchangeImplementations(boldSystemFontMethod!, myBoldSystemFontMethod!)
let italicSystemFontMethod = class_getClassMethod(self, #selector(italicSystemFont(ofSize:)))
let myItalicSystemFontMethod = class_getClassMethod(self, #selector(myItalicSystemFont(ofSize:)))
method_exchangeImplementations(italicSystemFontMethod!, myItalicSystemFontMethod!)
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!)
}
}
}
코드 설명을 해 보겠습니다!
UIFont.systemfont(ofSize: ~)
UIFont.boldSystemfont(ofSize: ~)
UIFont.italicSystemfont(ofSize: ~)
기본적으로, 위와 같은 기본 UIFont 내장함수를 변경하는 일입니다.
systemfont(ofSize: ~) < > mySystemFont(ofSize:~)
boldSystemfont(ofSize: ~) <> myBoldSystemfont(ofSize: ~)
italicSystemfont(ofSize: ~) <> myItalicSystemfont(ofSize: ~)
위에서는 지정하고자 하는 폰트를 각각 원하는 위치의 Struct에 위치시키고,
convenience init(~)
을 통해 원하는 파라미터만 변경한 후 이니셜라이징 해 줍니다.
폰트가 만들어질 때 호출되는 함수가 달라지게 됩니다. 기본적인 세가지 시스템 함수를 변경해주었습니다.
다르게 추가하는 방법도 있는데, 숙지하게 되면 다시 적겠습니다!
이후, AppDelegate에서
override init() {
super.init()
UIFont.overrideInitialize()
}
적용시켜주면 완성되게 됩니다. 실행 사진은 다음과 같습니다.
아니 잘 보이지 않으니까,,,몇개를 또 찍어보겠습니다...(억울) 사실 티 많이 납니다
이건 티가 좀 나네요. 왼쪽은 디폴트 시스템폰트, 오른쪽은 스포카한산즈 입니다!
질문이나 오류가 있다면 댓글 달아주시면 감사하겠습니다.
StackOverflow, https://stackoverflow.com/questions/46404557/changing-all-uilabel-fonts-in-app-depending-on-current-font-weight-using-swift-4
'iOS' 카테고리의 다른 글
[iOS] 개인 개발자 계정 구매하기, 12만 9천원 내기 (0) | 2020.06.19 |
---|---|
[iOS] UIDynamicAnimatior, UICollisionBehavior, UIGravityBehavior (2) | 2020.06.13 |
[iOS] 화면전환 애니메이션 커스텀하기 (2) UIViewControllerAnimatedTransitioning, (NavigationController) (0) | 2020.05.23 |
[iOS] 화면전환 애니메이션 커스텀하기 - CGAffineTransform, animateTransition [1] (3) | 2020.05.15 |
[iOS] SideBar (3) | 2020.05.09 |