preferredFont와 UIFontMetrics

 
안녕하세요 :) Zedd입니다.
2021 제1차 정보접근성 오픈 아카데미에서 인상깊게 본 것 중 하나가 UIFontMetrics인데,
얼른 공부해보고싶더라구요!

# Dynamic Type

사용자가 원하는 Text(Content) Size Category를 선택할 수 있도록 하는 기능.
명시적으로 Text size를 입력하는게 아니라, category를 지정하는 것.

# 앱이 Dynamic Type을 지원하는 법

text에 font크기를 지정할 때,
let label = UILabel() label.font = UIFont.systemFont(ofSize: 16, weight: .regular)
뭐 대충 이렇게 size와 weight를 지정해줄텐데, 이렇게 하면 Dynamic Type을 지원 할 수 없다.
왜냐?
notion imagenotion image
font size를 더 키웠지만, 나는 size를 "16"으로 고정해놨기때문.
Dynamic Type을 지원하려면 Text Style을 사용하면 된다.
[스토리보드]
notion imagenotion image
기본적으로 Font에 저렇게 들어가있을텐데,
notion imagenotion image
Font부분을 System에서 Text Style중 하나를 선택하게 하면 된다.
[코드]
let label = UILabel() label.font = UIFont.preferredFont(forTextStyle: .body)
이렇게 TextStyle만 지정하면
notion imagenotion image
notion imagenotion image
notion imagenotion image
notion imagenotion image
이렇게 Dynamic Type을 지원하는 앱으로 변신!

# 설정 왔다갔다 하기 귀찮...

2가지 방법이 있다.
[1] 빌드 후 Environment Overrides 클릭
notion imagenotion image
Text부분을 On하고 바꿔주면 된다.
[2] Accessibility Inspector 사용
[1]보다는 귀찮아서 이 방법은 추천하지 않는다. 하지만 알아놓으면 좋으니까!
notion imagenotion image
notion imagenotion image
notion imagenotion image
Font Size에서 조절하면 된다.

# 바로 바로 적용이 안됨.

원래 바로바로 적용이 안되는게 맞고 따로 작업을 해줘야한다.
[스토리보드]
notion imagenotion image
[코드]
let label = UILabel() label.font = UIFont.preferredFont(forTextStyle: .body) label.adjustsFontForContentSizeCategory = true ✅
이렇게 하면 바로바로 변경이 될 것이다.
notion imagenotion image
이것 이외에도, 만약 설정의 Font size category가 변경될 때 마다 뭔가 해주고싶다면,
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) { super.traitCollectionDidChange(previousTraitCollection) // code }
traitCollectionDidChange을 override하면 된다.
여기서 Font 업데이트 시켜줘도 됨.

# 설정 Font size category를 얻어오고싶다.

UIApplication.shared.preferredContentSizeCategory or self.traitCollection.preferredContentSizeCategory
를 통해 현재 Font size category를 얻어올 수 있다.
왼쪽 그림처럼 기본적으로 7단계의 category가 있고, Larger Accessibility Sizes를 on하면 5단계가 더 늘어난다.
총 12단계 조절가능.
extraSmall small medium large extraLarge extraExtraLarge extraExtraExtraLarge // Larger Accessibility Sizes On accessibilityMedium accessibilityLarge accessibilityExtraLarge accessibilityExtraExtraLarge accessibilityExtraExtraExtraLarge
이름 정말...직관적..ㅎ

# Larger Accessibility Sizes가 On인지 Off인지?

UIApplication.shared.preferredContentSizeCategory.isAccessibilityCategory or self.traitCollection.preferredContentSizeCategory.isAccessibilityCategory

# 각 Category를 지정했을 때 Font size가 어떻게 나오는지 궁금해

내가 TextStyle을 Body로 지정하고, extraLarge category로 지정했을 때
Font Size가 어떻게 되는지 궁금할 수 있다.
notion imagenotion image
notion imagenotion image
상단 탭으로 Category를 지정하면 각 Text Style의 Font Size와 Weight을 확인할 수 있다.

# 나는 CustomFont로 Dynamic Type을 지원하게 하고싶어

TextStyle을 지정하면,
notion imagenotion image
그냥 이게 전부인데..Custom Font를 사용하고 싶다면 UIFontMetrics을 사용하면 된다.

# UIFontMetrics

Dynamic Type을 지원하기 위해 custom font를 받을 수 있는 utility object.
1. 그냥 나는 Text Style안쓸거고, Category에 맞게 그냥 scale만 됐으면 좋겠어
let customFont = UIFont(name: "Kefa", size: 35)! label.font = UIFontMetrics.default.scaledFont(for: customFont) ✅
그럴 땐 이렇게 사용하면 된다.
notion imagenotion image
기본적으로 Body Text Style이 사용되므로 (From WWDC) 전부 일정하게 커진다.
2. 나는 TextStyle에 맞게 scale되었으면 좋겠어.
let customFont = UIFont(name: "Kefa", size: 35)! label.font = UIFontMetrics(forTextStyle: .headline).scaledFont(for: customFont) ✅
이런식으로 textStyle을 지정해주면 된다.
참고