Intrinsic Content Size

이원희·2021년 2월 9일
0

📱 iOS

목록 보기
15/24
post-thumbnail

오늘은 Intrinsic Content Size에 대해서 알아보자!

Intrinsic Content Size

Intrinsic Content Size는 번역하면 고유 콘텐츠 크기라고 한다.
이렇게만 말하면 무슨 말인지 잘 모르겠으니 공식문서Apple Document Archive를 확인해보자.

  • Intrinsic Content Sizeview자연스러운 사이즈이다.
  • 이때의 사이즈는 view의 속성들만 고려한 사이즈이다.
  • 예를 들어, UIButtonIntrinsic Content Size Title Size + margin이다.
  • 또한, 모든 view에 Intrinsic Content Size가 있는 것은 아니다.

View와 Intrinsic Content Size

흐음.. 모든 view에 Intrinsic Content Size가 있는건 아니라는데 어떤 view들이 Intrinsic Content Size를 가지고 있는지 확인해보자.

  • UIView: Intrinsic Content Size가지고 있지 않다.
  • UISlider: iOS 환경에서는 widthIntrinsic Content Size에 정의되어 있다.
    (이 부분은 현재는 바뀐거 같다. 아래에서 얘기해보겠다...)
  • UILabel, UIButton, Switch, UITextField: width, height 모두 Intrinsic Content Size에 정의되어 있다.
  • UITextView, UIImageView: 콘텐츠 크기에 따라 다를 수 있다.

코드로 확인해보자 (+ UISlider에 대해)

Intrinsic Content Size를 가지고 있지 않은 UIView
width만 가지고 있다는 UISlider
width, height 모두 가지고 있는 UIButton
위 세개에 대해서 Intrinsic Content Size를 확인해보자.

UIButtonUISlider를 위와 같이 추가했다.

@IBOutlet weak var slider: UISlider!
@IBOutlet weak var button: UIButton!

override func viewDidLoad() {
	super.viewDidLoad()
        
        print("UIView - (w: \(self.view.intrinsicContentSize.width), h: \(self.view.intrinsicContentSize.height))")
        print("UISlider - (w: \(slider.intrinsicContentSize.width), h: \(slider.intrinsicContentSize.height))")
        print("UIButton - (w: \(button.intrinsicContentSize.width), h: \(button.intrinsicContentSize.height))")
    }

하나씩 봐보자.
Intrinsic Content Size가 없는 UIView는 width, height 모두 -1이 출력되고 있다.
UISlider는 마지막에 보도록 하고,
width, height 모두를 가지고 있는 UIButton두 항목 모두 잘 나오고 있다.

❗️UISlider는 width를 가지고 있다고 했는데 실제로 찍어보니 height를 가지고 있었다;; ❗️

왤까...
위에 각각의 View들이 갖는 Intrinsic Content Size 항목에 대한 얘기는 Apple Document Archive에서 참고했다.

더이상 업데이트 되지 않는 라이브러리들이나 참고사항들이 있는 곳이라고 한다.

❗️ 그럼 UISlider는 어떻게 바뀌었나 확인해보자 ❗️

공식문서에 따르면 Intrinsic Content Size높이는 UISlider의 최소, 최대 이미지의 Intrinsic Content Size에 따라 결정된다고 한다.


Intrinsic Content Size 변경하기

Intrinsic Content Size는 view의 현재 콘텐츠를 기반으로 한다.

UILabelUIButtonIntrinsic Content Size표시되는 text의 양과 사용된 글꼴을 기반으로 한다.


UILabel

가운데에 UILabel을 두고, 아래의 UIButton을 클릭하면 UILabel text가 길어지도록 해보자.

@IBOutlet weak var testLabel: UILabel!

override func viewDidLoad() {
	super.viewDidLoad()
        
        print("❗️ testLabel - (w: \(testLabel.intrinsicContentSize.width), h: \(testLabel.intrinsicContentSize.height))")
        
}
    
@IBAction func tapAddTextButton(_ sender: UIButton) {
	print("👋")
        testLabel.text = "hihi\nhihihi\nhihihihi"
        print("❗️ testLabel - (w: \(testLabel.intrinsicContentSize.width), h: \(testLabel.intrinsicContentSize.height))")
}

오호....
UILabelIntrinsic Content Size표시되는 text의 양과 사용된 글꼴을 기반으로 한다는데 UILabeltext 길이가 길어지니 Intrinsic Content Size도 변하는걸 확인할 수 있다.


UIImageView

다른 view들은 Intrinsic Content Size가 좀 더 복잡하다.

예를 들어, 빈 UIImageViewIntrinsic Content Size를 가지고 있지 않다.
하지만 이미지를 추가하면 Intrinsic Content Size이미지 크기가 된다.

가운데에 빈 UIImageVIew를 두고, 아래의 UIButton을 누르면 UIImageView에 이미지를 추가해보자.

@IBOutlet weak var testImage: UIImageView!

override func viewDidLoad() {
        super.viewDidLoad()
        
        print("❗️ testImage - (w: \(testImage.intrinsicContentSize.width), h: \(testImage.intrinsicContentSize.height))")
}
    
@IBAction func tapAddTextButton(_ sender: UIButton) {
        print("👋")
        testImage.image = UIImage(named: "test1")
        print("❗️ testImage - (w: \(testImage.intrinsicContentSize.width), h: \(testImage.intrinsicContentSize.height))")
}

UIImageView일때는 Intrinsic Content Size가 없는 것을 확인할 수 있다.
UIButton을 누르면 UIImageView에 이미지가 추가되고 Intrinsic Content Size가 변하는 모습을 볼 수 있다.


UITextView

UITextViewIntrinsic Content Size는 콘텐츠, 스크롤 사용 여부 및 view에 적용된 제약 조건에 따라 달라진다.

스크롤이 활성화 된 경우에는 Intrinsic Content Size없다.
스크롤이 비활성화 되어 있는 경우 view의 Intrinsic Content Size는 줄바꿈 없는 텍스트 크기를 기준으로 계산된다.

텍스트에 줄바꿈(return)이 없을 때는 텍스트를 한 줄로 표시할때의 높이와 너비를 계산한다.
UITextView에 제약이 있는 경우는 제약 조건을 만족시키면서 콘텐츠를 표시할 수 있도록 Intrinsic Content Size를 조정한다.


Content Hugging, Compression Resistance

AutoLayout은 각 width, height마다 한 쌍의 제약 조건을 사용하여 view의 Intrinsic Content Size를 나타낸다.

// Compression Resistance
View.height >= 0.0 * NotAnAttribute + IntrinsicHeight
View.width >= 0.0 * NotAnAttribute + IntrinsicWidth
 
// Content Hugging
View.height <= 0.0 * NotAnAttribute + IntrinsicHeight
View.width <= 0.0 * NotAnAttribute + IntrinsicWidth

Content Hugging은 view를 안쪽으로 당겨서 콘텐츠 주변에 꼭 맞도록 한다.
Compression Resistance는 콘텐츠를 자르지 않도록 view를 밖으로 밀어낸다.

여기서 더 자세하게 알아보자.


CustomView와 Intrinsic Content Size

  • custom view에는 일반적으로 레이아웃 시스템이 인식하지 못하는 내용들이 표시된다.
  • Intrinsic Content Size 프로퍼티를 설정하면 custom view에서 콘텐츠에 따라 원하는 크기를 레이아웃 시스템에 전달할 수 있다.
  • Intrinsic SizeContent Frame과 독립적이여야 한다.
    (변경된 높이를 기반으로 변경된 너비를 레이아웃 시스템에 동적으로 전달한 방법이 없어서)

그렇다면 CustomView에서 Intrinsic Content Size를 어떻게 관리?할 수 있을까?

공식문서에서 invalidateIntrinsicContentSize() 메서드를 찾았다!

invalidateIntrinsicContentSize()

invalidateIntrinsicContentSize()Intrinsic Content Size무효화하는 메서드라고 한다.
customView에서 뭔가가 변했을때 Intrinsic Content Size무효화시키도록 호출한다.
이를 통해 제약조건 기반의 레이아웃 시스템은 다음 레이아웃 단계에서 새로운 Intrinsic Content Size를 고려한다.


마무리

오늘은 Intrinsic Content Size에 대해 알아봤다.
내용이 별로 안 길줄 알았는데 생각보다 길게 나왔다.
그래도 UIScroll에 대해 알게된건 좋은 수확인거 같다!
그럼 이만👋

0개의 댓글