안녕하세요!
오늘은 UIButton title의 CustomFont 적용과, UIButton.COnfiguration에 대해서 알아보겠습니다!
먼저, 제가 직면한 상황을 먼저 설명하고 그에 따른 해결 방법과 개념을 정리해 볼게요!
아래는 조금 더 직관적인 설명을 위해서 간결한 말투를 사용할 테니 양해부탁드려요 :) 그렇지만 100% 제가 작성한 거 맞다는 거..🥹
[ 문제상황 ]
1. Button을 Custom Class로 개발하여 재사용이 가능하도록 하려헀다. (CSButton)
2. CSButton 내부에 setConfiguration 함수를 정의해서 backgroundColor, titlefont, radius 등을 미리 설정해 뒀다.
3. radius나 backgroundColor는 잘 설정이 되는데, font가 이상하게 적용이 잘 안 됐다.
4. customFont를 사용 중이다.
[ 해결과정 ]
[ 가정 1 ]
먼저, UIFont의 CustomFont가 잘 적용됐는지 확인이 필요했다.
CustomFont 적용방법 ( Adding a Custom Font to your App : 공식문서 )
CustomFont의 적용과정에 대해서 먼저 설명하자면,
- 다운로드한 폰트파일을 프로젝트폴더 내에 저장해 준다.
- info.plist에도 다음과 같이 폰트를 사용한다고 명시해줘야 한다. 이때, 확장자까지 다 넣었는데, 검색해 보니 폰트를 다운로드할 때 두 가지 확장자 버전이 있는데
.otf : Open Type Font
.ttf : Tru Type Font
xCode는 고맙게 두 가지 모두 지원하니 아무거나 골라서 사용하면 된다.
- 이제 UIfont에서 CustomFont를 불러와서 사용하면 되는데, 나는 어차피 자주 쓸 폰트들이라서 extension에 넣어두고 enum으로 관리했다. 사용하는 방법을 찾다 보니 사람들마다 사용하는 방식이 다 달랐는데, 프로젝트에 따라서 편하게 사용하면 될 것 같다.
이때, 조심해야 할 것이 있다.
**폰트파일명과 실제 폰트를 불러올 때 사용하는 이름이 다를 수도 있기 때문에, xCode에서 사용하는 폰트의 파일명을 정확하게 확인해 보기 위해 다음과 같은 과정을 통해서 확인해 볼 수 있다. ( 공식문서 참조 ) 이렇게 하면 실제 사용하는 폰트들의 이름을 확인할 수 있고 우리는 이 이름들을 사용해서 UIFont를 init 할 것이기 때문에 print 한 값대로 enum을 작성해 줬다.
for family in UIFont.familyNames.sorted() {
let names = UIFont.fontNames(forFamilyName: family)
print("Family: \(family) Font names: \(names)")
}
- UIFont.init(name: , size: )를 사용해서 CustomFont를 사용한다. 나는 extension을 이용해서 다음과 같이 컴포넌트화 했다. 디자인 시스템에 따라서 지정된 크기나 굵기가 있을 테니 맞춰서 커스텀하면 된다. 공식문서에서는 guard let을 사용해서 에러를 방지하는 방법을 권장하고 있긴 하지만, 어차피 테스트를 거쳐서 폰트를 사용할 것이기 때문에 폰트가 불러와지지 않는 상황을 가정하지 않고 강제언랩 핑해서 사용했다.
[ 가정 2 ]
2. 폰트자체가 잘 불러와지고 있는 것은 확인했고, 그렇다면 Button을 그릴 때 시점이 잘못되었거나, 불필요하거나 필요한 코드를 잘못 사용한 경우라고 판단했다.
그래서 코드를 확인했고, 내가 초기 테스트를 위해서 적어둔 코드를 발견했다.
self.configuration = .plain()
여기서 self는 UIButton이다.
먼저 Configuration에 대해서 먼저 알고 넘어가자.
UIButton.Configuration
configure 메서드는 iOS 15 이후 도입된 기능으로 버튼의 모든 시각적 요소와 동작을 Configuration 객체를 통해서 관리하게 해 준다.
즉, 다시 말해서 CodebaseUI에서 기존에 UIfont, radius, padding, background 등을 일일이 코드로 작성해야 했다면 Storyboard에서 button의 스타일을 선택할 수 있는 것처럼 configure를 통해서 어느 정도 세팅된 버튼들을 가져와서 사용할 수 있다는 말이다.
장점은, 당연히 코드의 양을 줄이고 button을 규격화해서 재사용하기 쉽다는 것이고,
단점은 기존의 titleLabel이나, imageVIew와 같은 속성에 직접 접근하여 제어할 때 configure방식과 충돌이 일어날 수 있다는 점이다.
내가 Custom Font가 titleLabel에 적용이 안된 이유가 이것이었는데, 아래에 문제해결에서 조금 더 자세히 작성하겠다.
또한 configuration은 normal, highlighted, disabled에 따라 다른 스타일을 적용할 수 있게 해 준다. 내가 처음 개발 할 때만 해도 normal, hilight 같은 속성을 메서드에 파라미터로 넣지는 않았던 것 같다.
앞서 말했던 것과 같이 나는 configuration을 plain으로 사용하고 있었고, 이 때문에 CSButton의 style을 정의하는 메서드에서도, VC에서도 아무리 font를 적용해도 기본스타일을 벗어나지 않았다.
- 버튼을 그리는 시점 때문에 스타일이 덮어씌워지는 것.
두 가지 방법이 있었다.
첫 번째는 configure를 사용하지 않거나. none 처리를 통해서 custom 할 수 있도록 조절해 주는 것
self.configuration = .none
두 번째는 configure를 사용하여 다른 속성들을 편하게 사용하면서도 font와 같은 변하지 않는 부분만 따로 그려주기 위해서 layoutSubViews에서 한번 더 업데이트시켜주는 것
public override func layoutSubviews() {
super.layoutSubviews()
self.titleLabel?.font = UIFont.heading_1_UL
}
방금 언급한 대로 configure를 사용해서 스타일을 적용하는데 더 편하게 하면서도 font와 같은 attribute만 custom 하고 싶을 때는 layoutSubViews를 사용하면 될 것 같고, 나는 명시적으로 코드로 커스텀해주는 것이 익숙해서 그렇게 진행했다.
[ 결론 ]
configuration을 사용하면 button의 다양한 스타일 attribute를 한 번에 지정하고 덮어씌워지기 때문에 custom Font를 사용하는 방법이 잘못되지 않았음에도 적용이 되지 않았다.
configure를 사용하지 않거나, layoutSubViews를 통해서 라이프사이클을 이용해 마지막에 attribute를 업데이트해줄 수 있다.
이렇게 오늘은 제가 마주한 문제들을 해결했던 과정에서 알게 된 UIFont 적용법, 파일이름 확인하는 법, UIButton의 Configuration의 개념 및 종류와 특징에 대해서 정리해 봤습니다.
피드백은 언제나 환영이니 수정할 것이나 이상한 부분이 있다면 가감 없이 알려주시면 감사하겠습니다!
'SwiftUI' 카테고리의 다른 글
[SwiftUI] Tutorial 05 - MapKit 사용 기초, Divider (1) | 2023.12.29 |
---|---|
[SwiftUI] Tutorial 04. Custom Image View 만들기 - shadow, overlay, shape (0) | 2023.12.17 |
[SwiftUI Tutorial] 03. Stack 사용하기 (0) | 2023.11.04 |
[SwiftUI] SwiftUI Tutorial02 - Customize the text view (0) | 2023.11.04 |
[SwiftUI] 미리보기, 프로젝트 생성 (0) | 2023.10.31 |