관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] UILabel의 높이 static하게 가져오는 방법? (UILabel height 계산) 본문

iOS 응용 (swift)

[iOS - swift] UILabel의 높이 static하게 가져오는 방법? (UILabel height 계산)

jake-kim 2024. 3. 18. 01:08

UILabel의 높이 가져오는 경우

  • UILabel의 크기를 뷰가 다 그려지기 전에 static하게 알아와야하는 경우?
  • UITableView와 UITableViewCell을 사용할때, 뷰가 다 그려지기 전에 모든 Cell의 크기를 알아와야하는 경우? (이때 만약 UILabel만 동적으로 변한다면 UILabel의 높이를 구해야하는 상황)

UILabel의 높이 구하는 방법

  • sizeToFit()을 사용하여 구현
    • 이 값을 사용하면 뷰의 내부 content크기에 맞게 즉각 계산됨

https://developer.apple.com/documentation/uikit/uiview/1622630-sizetofit

  • UIView의 extension 메서드이므로 UIView 계열은 모두 사용 가능
extension UIView {
...
    open func sizeToFit()
}

 

  • 알아내려는 UILabel의 속성을 그대로 주고 (text, numberOfLines, width, font값) sizeToFit()을 호출해주면 뷰가 다 그려지기 전에도 높이 구하기가 가능

예시)

  • cell을 여러개 가지고 있는 UITableView에서 cell을 그리기 전에 cell들의 height를 구하는 방법?

(코드: https://github.com/JK0369/ExLabelStaticHeight)

  • 알아내고싶은 UILabel은 MyCell의 label
final class MyCell: UITableViewCell {
    enum Const {
        static let labelHorizontalMargin = 24.0
    }
    
    private let label = {
        let l = UILabel()
        l.numberOfLines = 0
        l.textColor = .black
        l.font = .systemFont(ofSize: 24)
        l.translatesAutoresizingMaskIntoConstraints = false
        return l
    }()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        contentView.addSubview(label)
        NSLayoutConstraint.activate([
            label.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: Const.labelHorizontalMargin / 2),
            label.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -Const.labelHorizontalMargin / 2),
            label.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
            label.topAnchor.constraint(equalTo: contentView.topAnchor),
        ])
    }
    
    required init?(coder: NSCoder) {
        fatalError()
    }
    
    func configure(text: String) {
        label.text = text
    }
}
  • 이 label이 화면에 그려지기 전에 높이를 가져오려면 이 label과 동일한 속성(text, numberOfLines, width, font값) 입력 후 sizeToFit()을 호출
  • 중요한 사항
    • label을 만들때 cell에 있는 width값과 동일하게 설정해야함
    • height값을 동적으로 변할것이므로 .greatestFiniteMagnitude로 설정
static func getLabelHeight(text: String) -> CGFloat {
    let label = UILabel(
        frame: .init(
            x: .zero,
            y: .zero,
            width: UIScreen.main.bounds.width - MyCell.Const.labelHorizontalMargin,
            height: .greatestFiniteMagnitude
        )
    )
    label.text = text
    label.numberOfLines = 0
    label.font = .systemFont(ofSize: 24)
    label.sizeToFit()
    let labelHeight = label.frame.height
    return labelHeight
}

* 전체 코드: https://github.com/JK0369/ExLabelStaticHeight

* 참고

- https://developer.apple.com/documentation/uikit/uiview/1622630-sizetofit

Comments