大器晩成

[UILabel] - Padding 본문

iOS/UiKit

[UILabel] - Padding

zerobugpark 2025. 2. 20. 23:40

 

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을 사용할 수 있습니다.

 

 

 

drawText 만 사용해서 그렸을 때

 

패딩을 추가해서 그렸는데, 왜 커스텀 레이블을 사용하고 있는 첫 번째 레이블과 두 번째 레이블은 뭔가 패딩이 적용된 거 같기도 하면서, 텍스트가 잘린 형태로 나옵니다.

 

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

 

728x90