Today I Learn

Today I Learn: UILabel 내부 Padding 설정하기

Goniii 2025. 3. 6. 21:08

 

위와 같이, UILabel은 기본적으로 텍스트와 레이블 경계 사이의 여백을 설정할 수 있는 속성을 제공하지 않는다. 아래처럼 UILabel 내부 패딩을 제공해야 되는 상황에서 커스텀 UILabel을 만들어서 적용하는 방법을 포스팅하려고 한다.

 

 

UILabel 내부 패딩 설정 방법: drawText(in:) 인스턴스 메서드 사용

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

 

drawText(in:)

공식문서에 나오듯 이 인스턴스 메서드는 지정된 사각형 내부에서 라벨의 텍스트를 그리는 메서드이다. Discussion에 따르면, 이 메서드를 직접 호출하지 말고 Override하여 재정의 후 구현하는 것을 권장한다.

override func drawText(in rect: CGRect) {
    super.drawText(in: rect)
}
  • rect: UILabel이 텍스트를 그리는 데 사용할 영역
  • super.drawText(in: rect): 기본적인 UILabel의 텍스트 렌더링 로직을 실행
  • label의 텍스트 값이 그려질 때, rect에 관한 값을 수정할 때 해당 메서드를 사용한다.

여기서 rect는 UILabel의 영역을 뜻한다. CGRect.inset(by:) 메서드를 이용하여 UILabel 내부 inset을 설정할 수 있게 된다

 

 

https://developer.apple.com/documentation/corefoundation/cgrect/1624499-inset

 

inset(by:) | Apple Developer Documentation

Adjusts a rectangle by the given edge insets.

developer.apple.com

 

override func drawText(in rect: CGRect) {
    super.drawText(in: rect.inset(by: padding))
}

→ 원래의 UILabel의 drawText(in:)가 레이블의 bounds 전체에 텍스트를 그리는 반면, override 하여 위와 같이 inset을 주게 되면 rect의 공간을 줄여 텍스트의 padding이 생기게 되는 것이다

 

 

// UILabel 커스텀
class PaddingLabel: UILabel {
    private let padding: UIEdgeInsets
    
    // 패딩 값을 주입받아 재사용 가능하게 설계
    init(topPadding: CGFloat, leftPadding: CGFloat, bottomPadding: CGFloat, rightPadding: CGFloat) {
        self.padding = UIEdgeInsets(top: topPadding, left: leftPadding, bottom: bottomPadding, right: rightPadding)
        super.init(frame: .zero)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // UILabel에 패딩 추가
    override func drawText(in rect: CGRect) {
		    // rect에 inset 설정
        super.drawText(in: rect.inset(by: padding))
    }
}

 

 

하지만, 여기서 끝이 아니다

Padding 값 설정 이후 intrinsicContentSize를 재정의해주어야 한다

 

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

 

intrinsicContentSize

  • UIView가 자체적으로 계산한 콘텐츠의 크기를 의미
  • 즉, 뷰가 자신의 크기를 어떻게 결정하는지를 시스템에 알려주는 역할을 함
  • UIKit에서 제공하는 기본적인 뷰들은 intrinsicContentSize를 자동을 계산함

→ UILabel은 텍스트 내용을 기반으로 intrinsicContentSize 를 자동으로 결정함

 

Discussion

사용자 정의 뷰는 일반적으로 레이아웃 시스템에서 인식하지 못하는 콘텐츠를 표시합니다. 이 속성을 설정하면 사용자 정의 뷰가 콘텐츠에 따라 어떤 크기가 되기를 원하는지 레이아웃 시스템에 전달할 수 있습니다. 이 내재적 크기는 콘텐츠 프레임과 독립적이어야 합니다. 예를 들어, 변경된 높이에 따라 변경된 너비를 레이아웃 시스템에 동적으로 전달할 방법이 없기 때문입니다.
사용자 지정 보기에 주어진 차원에 대한 고유 크기가 없는 경우 해당 차원에 대해 noIntrinsicMetric을 사용할 수 있습니다.

 

→ padding 값을 변경해도 시스템이 변경을 인지하지 못하기 때문에 intrinsicContentSize 직접 조정해주어야 된다

    // intrinsicContentSize를 직접 조정하여 최소 높이를 보장하면
   override var intrinsicContentSize: CGSize {
        let size = super.intrinsicContentSize // 기본 콘텐츠 사이즈
        
        // 가본 사이즈에 패딩 추가
        return CGSize(width: size.width + padding.left + padding.right,
                      height: size.height + padding.top + padding.bottom)
    }
  • 기본 컨텐츠 사이즈인 super.intrinsicContentSize에 추가로 패딩을 더해 설정

 

 

최종 코드

class PaddingLabel: UILabel {
    private let padding: UIEdgeInsets
    
    init(topPadding: CGFloat, leftPadding: CGFloat, bottomPadding: CGFloat, rightPadding: CGFloat) {
        self.padding = UIEdgeInsets(top: topPadding, left: leftPadding, bottom: bottomPadding, right: rightPadding)
        super.init(frame: .zero)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    // UILabel에 패딩 추가
    override func drawText(in rect: CGRect) {
        super.drawText(in: rect.inset(by: padding))
    }
    
    // intrinsicContentSize를 직접 조정하여 최소 높이를 보장하면
    override var intrinsicContentSize: CGSize {
        let size = super.intrinsicContentSize
        let minHeight = padding.top + padding.bottom + size.height // 최소 높이 보장
        return minHeight
    }
}

 

 

 

https://ios-development.tistory.com/698

 

[iOS - swift] padding label (UILabel에 padding값 주는 방법)

padding 주는 방법 보통 stackView에 label을 넣을때 UIView를 넣고 그 안에 다시 Label을 넣어서 layout을 조절할 수 있지만, UILabel에 따로 padding값을 주어서 사용 가능 Padding 주는 방법 - drawText(in:)에서 paddin

ios-development.tistory.com