Swift에서 채팅 UI를 다루고 있는 도중에 위와같은 intrinsicContentSize / Frame / bounds 이 부분에 대해 차이가 갑자기 궁금해졌다. 현재
if shouldShowProfile {
if shouldDateTime {
cellHeight = cell.youMsgTV.intrinsicContentSize.height + 10 + cell.youProfileIV.frame.height + cell.dateLB.intrinsicContentSize.height
} else {
cellHeight = cell.youMsgTV.intrinsicContentSize.height + 10 + cell.youProfileIV.frame.height
}
} else {
if shouldDateTime {
cellHeight = cell.youMsgTV.intrinsicContentSize.height + 10 + cell.dateLB.intrinsicContentSize.height
} else {
cellHeight = cell.youMsgTV.intrinsicContentSize.height + 10
}
}
컬렉션 뷰에서 해당 뷰들의 높이를 구해서 셀의 총 높이를 구하고 있었는데 intrinsicContentSize / Frame / bounds 이 3가지가 각각 다른 높이를 가지고 있더라...
셀의 높이도 각기 다르게 나와서 찾아보았다.
📌 intrinsicContentSize, frame, bounds 차이 설명
iOS 개발에서 UIView를 다룰 때, intrinsicContentSize, frame, bounds는 각각 다른 개념이야.
이 개념들을 이해하면 레이아웃을 정확하게 조절할 수 있어.
1️⃣ intrinsicContentSize (내재된 크기, 콘텐츠의 본질적인 크기)
✅ 개념
- 뷰 자체의 **콘텐츠 크기(Content Size)**를 의미함
- 특정한 크기가 정해져 있는 UI 요소들(Label, Button 등)에서 사용됨
- UILabel, UIButton 등의 뷰는 기본적으로 콘텐츠 크기에 맞게 자동으로 크기가 결정됨
- UIView에서는 기본적으로 (UIView.noIntrinsicMetric, UIView.noIntrinsicMetric) 반환 → 크기가 지정되지 않음
intrinsicContentSize는 UIView 자체의 콘텐츠 크기를 결정하는 속성이야.
일반적으로 UILabel, UIButton, UIImageView 같은 뷰는 자신의 콘텐츠 크기를 기반으로 크기가 결정됨.
✅ 특징
- CGSize(width: height:) 값을 반환하며, UIView의 크기를 자동으로 결정하는 역할을 함.
- UILabel, UIButton 같은 뷰들은 내부 콘텐츠(텍스트, 이미지 등)의 크기를 기반으로 intrinsicContentSize를 가짐.
- Auto Layout을 사용할 때 크기를 명시적으로 지정하지 않아도 이 값이 존재하면 자동으로 크기를 설정할 수 있음.
- 기본적으로 UIView는 intrinsicContentSize가 .zero (즉, 크기 없음)이지만, 컨텐츠 기반의 뷰들은 자체적으로 값을 가짐.
✅ 사용 예시
let label = UILabel()
label.text = "Hello, world!"
print(label.intrinsicContentSize) // (95.0, 20.5) → 텍스트 크기에 맞게 자동 결정
➡ intrinsicContentSize를 지원하는 뷰는 Auto Layout을 사용할 때 크기가 자동으로 설정됨
✅ intrinsicContentSize를 오버라이드해서 크기 설정
class CustomView: UIView {
override var intrinsicContentSize: CGSize {
return CGSize(width: 200, height: 100)
}
}
➡ 이렇게 하면 Auto Layout에서 명시적으로 크기를 설정하지 않아도 자동으로 적용됨
2️⃣ frame (전체 좌표, 부모 뷰 기준)
✅ 개념
- 슈퍼뷰(부모 뷰) 기준으로 뷰의 위치와 크기를 나타냄
- (x, y, width, height) 형태로 구성됨
- UIView의 크기와 위치를 조절할 때 많이 사용됨
✅ 특징
- CGRect(x: y: width: height:) 형태로 표현됨.
- 뷰의 좌표와 크기를 포함하는 전체적인 박스를 의미함.
- 슈퍼뷰(부모 뷰)의 좌표계를 기준으로 위치가 정해짐.
✅ 사용 예시
let view = UIView()
view.frame = CGRect(x: 50, y: 100, width: 200, height: 150)
➡ 이 뷰는 부모 뷰에서 (50, 100) 위치에 있고, 크기는 (200, 150)
✅ frame의 값 읽기
print(view.frame.origin) // (50.0, 100.0)
print(view.frame.size) // (200.0, 150.0)
✅ frame 변경 시 주의점
- frame.origin을 변경하면 뷰의 위치가 변하지만, bounds.origin은 변하지 않음
- frame.size를 변경하면 뷰 크기가 변함
3️⃣ bounds (자신 기준 크기)
✅ 개념
- **자기 자신(View)**을 기준으로 하는 크기와 위치를 나타냄
- 보통 (0, 0, width, height) 형태로 사용됨
- bounds.origin을 변경하면 뷰의 내부 콘텐츠가 이동하는 효과 발생
bounds는 뷰의 "자기 자신" 기준으로 크기와 위치를 나타내는 속성이야.
쉽게 말해, frame은 슈퍼뷰 기준이고, bounds는 자기 자신 기준이야.
✅ 특징
- CGRect(x: y: width: height:) 형태
- (0, 0)에서 시작하는 자기 자신의 좌표계를 기준으로 크기와 위치를 정의
- x, y는 보통 0, 0인데, ScrollView 같은 경우에는 스크롤되면서 bounds.origin이 변할 수 있음.
✅ 사용 예시
let view = UIView()
view.bounds = CGRect(x: 0, y: 0, width: 200, height: 150)
➡ 크기는 frame과 동일하지만, x: 0, y: 0이기 때문에 자기 자신 기준 좌표
5️⃣ intrinsicContentSize, frame, bounds 관계
let label = UILabel()
label.text = "Hello"
label.sizeToFit()
print("intrinsicContentSize:", label.intrinsicContentSize)
print("frame:", label.frame)
print("bounds:", label.bounds)
출력 예시
intrinsicContentSize: (50.0, 20.0)
frame: (0.0, 0.0, 50.0, 20.0)
bounds: (0.0, 0.0, 50.0, 20.0)
➡ intrinsicContentSize는 frame.size와 동일해지고, bounds.size도 같음
6️⃣ 정리
intrinsicContentSize | 콘텐츠 크기 | 내부 콘텐츠(텍스트, 이미지 등) 크기에 따라 자동 조절 |
frame | 부모 뷰 기준 | 뷰의 위치와 크기 (뷰가 화면에서 어디에 있는지) |
bounds | 자기 자신 기준 | 뷰 내부의 크기와 내부 콘텐츠의 위치 조정 |
✅ 레이아웃 잡을 때 frame을 직접 조절하는 것보다 intrinsicContentSize나 Auto Layout을 활용하는 것이 더 안정적!
1️⃣ intrinsicContentSize → 콘텐츠 크기 기반으로 자동 크기 결정
2️⃣ frame → 슈퍼뷰 기준의 위치와 크기
3️⃣ bounds → 자기 자신 기준의 크기
🚀 즉,
- 뷰의 위치를 변경할 때는 frame.origin을 조정
- 뷰 내부에서 좌표를 조정할 때는 bounds.origin을 조정
- UILabel, UIButton 같은 뷰는 intrinsicContentSize를 이용해 크기를 자동으로 설정
'Swift' 카테고리의 다른 글
Swift_ 변수의 종류 (0) | 2025.02.11 |
---|---|
Swift_ CoreData Model , extension , Struct (0) | 2024.08.02 |
Swift_ CoreData 적용기... (0) | 2024.07.24 |