Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- uitableview
- map
- UICollectionView
- 리펙터링
- Protocol
- Observable
- combine
- Human interface guide
- tableView
- RxCocoa
- 클린 코드
- rxswift
- ribs
- 애니메이션
- swiftUI
- 스위프트
- Refactoring
- ios
- SWIFT
- 리팩토링
- UITextView
- Xcode
- Clean Code
- MVVM
- HIG
- uiscrollview
- collectionview
- 리펙토링
- swift documentation
- clean architecture
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] UIButton 안의 UILabel, UIImageView 사용하면 안되는 이유 (볼드체 텍스트 활성화 문제, system font) 본문
iOS 응용 (swift)
[iOS - swift] UIButton 안의 UILabel, UIImageView 사용하면 안되는 이유 (볼드체 텍스트 활성화 문제, system font)
jake-kim 2023. 4. 20. 01:05UIButton 안의 UIImageView, UILabel 사용 시 주의사항
* UIButton하나로 UIButton, UILabel의 inset 다루는 방법은 이전 포스팅 글 참고
- 시스템 설정에서 볼드체 텍스트 활성화 할 경우 글자가 잘리는 이슈
일반적인 경우 | 볼드체 텍스트 활성화한 경우 |
|
- 볼드체 텍스트 활성화
- 왼쪽의 UIImageView가 오른쪽으로 이동하고 오른쪽의 UILabel도 왼쪽으로 이동한 상황
- 즉 inset 값들이 초기화된 상황
- 현재까지 전체 코드
import UIKit
class ViewController: UIViewController {
private let button: RoundableButton = {
let button = RoundableButton()
// title
button.setTitle("버튼", for: .normal)
button.setTitleColor(.white, for: .normal)
// image
let image = UIImage(named: "blog")?.imageWith(newSize: .init(width: 30, height: 30))
button.setImage(image, for: .normal)
// inset
let verticalSpace = 4.0
let horizontalSpace = 12.0
let interSpace = 3.0
button.contentEdgeInsets = .init(top: verticalSpace, left: horizontalSpace, bottom: verticalSpace, right: horizontalSpace)
button.imageEdgeInsets = .init(top: 0, left: -interSpace, bottom: 0, right: interSpace)
button.titleEdgeInsets = .init(top: 0, left: interSpace, bottom: 0, right: -interSpace)
button.backgroundColor = .lightGray
button.layer.borderColor = UIColor.lightGray.cgColor
button.layer.borderWidth = 1
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(button)
NSLayoutConstraint.activate([
button.centerYAnchor.constraint(equalTo: view.centerYAnchor),
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
])
}
}
extension UIImage {
func imageWith(newSize: CGSize) -> UIImage {
let image = UIGraphicsImageRenderer(size: newSize).image { _ in
draw(in: CGRect(origin: .zero, size: newSize))
}
return image.withRenderingMode(renderingMode)
}
}
final class RoundableButton: UIButton {
override func layoutSubviews() {
super.layoutSubviews()
layer.cornerRadius = frame.size.height / 2
}
}
볼드체 텍스트 활성화 시 발생하는 문제
- 볼드체를 활성화하면 UIButton안의 UIImageView, UILabel에 벌어지는 현상
- 레이아웃이 반영된 후 frame을 알기위해서 viewDidLayoutSubviews 메소드에서 UIImageView, UILabel의 frame을 찍어봐서 확인
- 각각 print(button.imageView?.frame), print(button.titleLabel?.frame)로 확인
- (x, y, width, height) 값을 확인
일반적인 경우 | 볼드체 텍스트 활성화 | |
UIButton.imageView | (9.0, 4.0, 30.0, 30.0) | (16.0, 4.0, 31.0, 30.0) |
UIButton.titleLabel | (45.0, 8.0, 32.0, 22.0) | (53.6, 8.0, 16.0, 22.0) |
- 볼드체를 활성화하면 x좌표가 변경되어서 titleLabel도 잘리는 것
- imageView의 경우 x좌표가 +7
- titleLabel의 경우 x좌표가 +8.6
- titleLabel은 system font이므로, bold 체로 설정하면 폰트도 semi bold로 변경됨
일반적인 경우 | 볼드체 텍스트 활성화 | |
button.titleLabel?.font | <UICTFont: 0x119f0ce90> font-family: ".SFUI-Regular"; font-weight: normal; font-style: normal; font-size: 18.00pt | <UICTFont: 0x105409610> font-family: ".SFUI-Semibold"; font-weight: normal; font-style: normal; font-size: 18.00pt |
해결 방법
- 가장 좋은 방법은 UIButton의 UIImageView와 UILabel을 사용하지 않고 직접 Custom View를 만들어서 사용할 것
- viewDidLayoutSubviews에서 frame값과 font값을 설정해도 시스템에서 설정한 우선순위가 높으므로, 다 무시됨
- UILabel의 adjustsFontSizeToFitWidth를 true로하여 UILabel이 잘리지 않게 하는 방법
일반적인 경우 | 볼드체 텍스트 활성화한 경우 |
'iOS 응용 (swift)' 카테고리의 다른 글
Comments