관리 메뉴

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

[iOS - swift] intinsicContentSize, sizeToFit, sizeThatFits (UILabel 크기를 텍스트에 맞추는 방법) 본문

iOS 응용 (swift)

[iOS - swift] intinsicContentSize, sizeToFit, sizeThatFits (UILabel 크기를 텍스트에 맞추는 방법)

jake-kim 2021. 7. 30. 23:27

UILabel의 이해

  • UILabel은 초기에 frame.size를 지정해주지 않으면 width, height가 0으로 세팅
  • text의 내용이 있더라도 0으로 존재
// 텍스트에 무엇이 존재하던지 frame.size 값은 0으로 초기화

class ViewController: UIViewController {

    lazy var titleLabel: UILabel = {
        let label = UILabel()
        label.textColor = .black
        label.text = "초기 텍스트"

        return label
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        titleLabel.center = view.center
        print(titleLabel.frame.size) // (0.0, 0.0)
        view.addSubview(titleLabel)
    }

}
  • size가 (0.0, 0.0)이므로 화면에도 역시 미표출

  • 뒤에서 알아볼 sizeToFit()를 사용하면 해결
class ViewController: UIViewController {

    lazy var titleLabel: UILabel = {
        let label = UILabel()
        label.textColor = .black
        label.text = "초기 텍스트"

        return label
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        titleLabel.center = view.center
        titleLabel.sizeToFit() // <- 추가
        view.addSubview(titleLabel)
    }
}

  • 주의할 점은 동적으로 바뀌는게 아니고, sizeToFit() 호출 시 내부 내용에 따라 view크기가 조절
    • ex) 나중에 text내용을 추가하면 view의 frame크기는 고정되어 있는 상태이므로 text가 잘리는 현상 발생
class ViewController: UIViewController {

    lazy var titleLabel: UILabel = {
        let label = UILabel()
        label.textColor = .black
        label.text = "초기 텍스트"

        return label
    }()

    override func viewDidLoad() {
        super.viewDidLoad()
        titleLabel.center = view.center
        titleLabel.sizeToFit()
        view.addSubview(titleLabel)
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        titleLabel.text = "실험 long 텍스트 실험 abcdefg"
    }
}

intinsicContentSize, sizeToFit(), sizeThatFits() 개념

  • intrinsicContentSize: '내용'을 기반으로 하는 고유 크기
    • view.intrinsicContentSize로 접근
lazy var titleLabel: UILabel = {
    let label = UILabel()
    label.textColor = .black
    label.text = "초기 텍스트"

    print(label.frame.size) // (0.0, 0.0)
    print(label.intrinsicContentSize) // (78.0, 20.333)
    label.frame.size = label.intrinsicContentSize // 사이즈 할당

    return label
}()
  • sizeToFit(): label.frame.size = label.intrinsicContentSize 코드와 동일한 효과
lazy var titleLabel: UILabel = {
    let label = UILabel()
    label.textColor = .black
    label.text = "초기 텍스트"
    label.sizeToFit()

    print(label.frame.size) // (78.0, 20.333)

    return label
}()
  • sizeThatFits(_:): 뷰가 계산을 할때 가장 적합한 크기인 '인수로 들어온 size'를 참고하며 size값을 반환
    • 단, '참고'를 하기 때문에 결과값은 intrinsicContentSize와 동일할수 있는 점 존재
lazy var titleLabel: UILabel = {
    let label = UILabel()
    label.textColor = .black
    label.text = "초기 텍스트"

    let size = CGSize(width: 12345, height: 1) // 임의의 값을 주어도 무방
    print(label.sizeThatFits(size)) // (78.0, 20.333)
    print(label.intrinsicContentSize) // (78.0, 20.333)
    print(label.frame) // (0.0, 0.0, 0.0, 0.0)

    return label
}()

* 응용 - 내부 content size에 따라 superview도 같이 변하는 view

 

* 참고

- IntrinsicContentSize: https://developer.apple.com/documentation/uikit/uiview/1622600-intrinsiccontentsize

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

- sizeThatFits(): https://developer.apple.com/documentation/uikit/uiview/1622625-sizethatfits

 

Comments