大器晩成
[UILabel] - Padding 본문
UIKit에서 UILabel을 사용할 경우 패딩 속성이 없어 View를 만들고 View안에 Label을 넣어서 관리하는 경우가 종종 있습니다.
불편함 때문에 찾다 보니 UILabel에도 패딩이 적용할 수 있어 간단하게 작성해보려고 합니다.
첫 번째 레이블과 두 번째 레이블은 패딩이 적용되었으며, 세 번째 레이블은 적용되지 않은 상태입니다.
커스텀하게 사용하기 위해서 Apple에서 제공하는 drawText 메서드를 통해, 기본 Padding을 지정해 줄 수 있습니다.
final class PaddingLabel: UILabel {
private let padding = UIEdgeInsets(top: 16.0, left: 16.0, bottom: 16.0, right: 16.0)
init() {
super.init(frame: .zero)
}
convenience init(boldStyle: Bool, fontSize: CGFloat) {
self.init()
font = boldStyle ? .boldSystemFont(ofSize: fontSize) : .systemFont(ofSize: fontSize)
textColor = .black
textAlignment = .center
layer.borderWidth = 1
layer.borderColor = UIColor.lightGray.cgColor
layer.cornerRadius = 2
clipsToBounds = true
}
override func drawText(in rect: CGRect) {
super.drawText(in: rect.inset(by: padding))
}
}
- rect.inset(by:) 메서드는 다음 처럼 구성되어 있어, func inset(by insets: UIEdgeInsets) -> CGRect Padding을 사용할 수 있습니다.
패딩을 추가해서 그렸는데, 왜 커스텀 레이블을 사용하고 있는 첫 번째 레이블과 두 번째 레이블은 뭔가 패딩이 적용된 거 같기도 하면서, 텍스트가 잘린 형태로 나옵니다.
UILabel은 intrinsicContentSize를 사용해서 텍스트의 높이와 길이에 따라 너비를 정할 수 있습니다. 이것 때문에, 기본적으로 UILabel은 크기를 지정해주지 않아도 iOS가 자동으로 너비를 설정할 수 있는 이유입니다.
근데 drawText에서 패딩을 주고 있기 때문에, 텍스트를 담는 뷰의 크기가 달라졌는데 intrinsicContentSize의 크기는 동일하니 문제가 발생한 것입니다.
intrinsicContentSize 속성을 재정의하여 패딩까지 포함하는 크기로 변경해 줘야 제대로 된 동작을 확인할 수 있습니다.
intrinsicContentSize은 get only 계산속성으로 content size + padding을 해준 값을 리턴해주고 있습니다.
재정의 했기 때문에 레이블을 그릴 때 재정의 된 intrinsicContentSize의 값을 이용해 레이블을 그리기 때문에 정상적으로 패딩이 적용된 것을 확인할 수 있습니다.
final class PaddingLabel: UILabel {
private let padding = UIEdgeInsets(top: 16.0, left: 16.0, bottom: 16.0, right: 16.0)
init() {
super.init(frame: .zero)
}
convenience init(boldStyle: Bool, fontSize: CGFloat) {
self.init()
font = boldStyle ? .boldSystemFont(ofSize: fontSize) : .systemFont(ofSize: fontSize)
textColor = .black
textAlignment = .center
layer.borderWidth = 1
layer.borderColor = UIColor.lightGray.cgColor
layer.cornerRadius = 2
clipsToBounds = true
}
// 텍스트 내의 패딩
override func drawText(in rect: CGRect) {
super.drawText(in: rect.inset(by: padding))
}
// 텍스트레이블의 사이즈를 패딩을 더해서 다시 정의해줌
override var intrinsicContentSize: CGSize {
var contentSize = super.intrinsicContentSize
contentSize.height += padding.top + padding.bottom
contentSize.width += padding.left + padding.right
return contentSize
}
@available(*, unavailable)
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
- 코드 베이스 기준이며, 스토리보드로 작업하시는 분들은 required init을 일부 수정해줘야 합니다.
참고자료
https://developer.apple.com/documentation/uikit/uilabel/drawtext(in:)
drawText(in:) | Apple Developer Documentation
Draws the label’s text, or its shadow, in the specified rectangle.
developer.apple.com
https://developer.apple.com/documentation/uikit/uiview/intrinsiccontentsize
intrinsicContentSize | Apple Developer Documentation
The natural size for the receiving view, considering only properties of the view itself.
developer.apple.com
'iOS > UiKit' 카테고리의 다른 글
Compositional Layout - 섹션마다 서로 다른 셀 적용해보기 (0) | 2025.03.03 |
---|---|
MapKit 사용법 (0) | 2025.02.05 |
CollectionView 3탄 - 셀의 크기를 개별적으로 변경 (0) | 2025.02.02 |
CollectionView 2탄 - 디바이스 별 Cell 크기 조정 (0) | 2025.01.29 |
CollectionView 1탄 - layout 설정 (0) | 2025.01.19 |