뷰를 그리면서 수없이 frame을 쓰고, 봐왔는데요.
오늘은 이 frame에 대해 알아보려고 합니다.
먼저 공식문서를 읽어볼까요 ?
frame
frame이란 superview 좌표계에서 뷰의 위치와 크기를 설명하는 직사각형을 의미합니다.
좀 더 자세히 Discussion까지 읽어봅시다.
레이아웃 작업 중 뷰의 크기와 위치를 설정하기 위해 사각형을 사용합니다.
이 속성을 설정하면 center 속성에서 지정한 점이 변경되고, bounds 사각형의 크기도 그에 맞게 변경됩니다.
frame 사각형의 좌표는 항상 포인트로 지정됩니다.
경고
transform 속성이 identity transform이 아닌 경우, 이 속성의 값은 정의되지 않으며 따라서 무시해야 합니다.
frame 사각형을 변경하면, draw(_:) 메서드를 호출하지 않고 뷰를 자동으로 다시 표시합니다.
frame 사각형이 변경될 때, draw(_:) 메서드를 호출하려면 contentMode 속성을 UIView.ContentMode.redraw로 설정하세요.
이 속성의 변경 내용은 애니메이션으로 표현할 수 있습니다.
그러나, transform 속성이 identity transform이 아닌경우, frame 속성의 값은 정의되지 않으며 수정해서는 안됩니다.
이 경우에는 center 속성을 사용하여 뷰의 위치를 다시 지정하고 bounds 속성을 사용하여 크기를 조정하세요.
음. .
frame은 superview 좌표계에서 뷰를 그리는 사각형으로 해당 사각형을 변경하면 자동으로 뷰가 다시 표시 표시된다는 걸 알 수 있네요.
위에서 frame을 설정하면 center 속성에서 지정한 점이 변경되고, bounds 사각형의 크기도 그에 맞게 변경된다고 나와있는데요.
그럼 bounds는 뭘까요 ?
bounds
bounds란 자기자신의 좌표계에서 뷰의 위치와 크기를 설명하는 직사각형을 의미합니다.
마찬가지로 자세히 살펴보면 내용은 아래와 같습니다.
기본 bounds의 원점은 (0, 0)이며 크기는 프레임 속성에 있는 직사각형의 크기와 동일합니다.
이 직사각형의 size를 변경하면 중심점을 기준으로 확대 또는 축소시킵니다.
또한, size를 변경하면 프레임 속성에 있는 직사각형의 크기도 변경되어 일치시킵니다.
bounds 직사각형의 좌표는 항상 포인트로 지정됩니다.
draw(_:) 메서드 관련 동작은 transform 특징을 제외하고 frame과 같습니다.
bounds는 frame과는 다르게 superview가 아닌 자기 자신의 좌표계 기준으로 뷰를 그리는 직사각형인 걸 알 수 있습니다.
흠 . . 공식문서를 살펴보며 대충 알아봤지만 뭔 소린지 잘 모르겠네요 . . 직접 뷰를 그리면서 알아봅시다 !
이와 같이 뷰를 그리고, frame과 bounds를 출력하면 결과는 아래와 같습니다.
1번째 뷰
[frame] (20.0, 79.0, 353.0, 719.0)
[bounds] (0.0, 0.0, 353.0, 719.0)
2번째 뷰
[frame] (50.0, 100.0, 253.0, 519.0)
[bounds] (0.0, 0.0, 253.0, 519.0)
3번째 뷰
[frame] (50.0, 100.0, 153.0, 319.0)
[bounds] (0.0, 0.0, 153.0, 319.0)
이를 통해, frame은 자신의 superview를 기준으로 좌표를 잡고,
bounds는 자기 자신을 기준으로 좌표를 잡는다는 것을 바로 이해할 수 있겠죠.
그럼 여기서 frame과 bounds를 각각 옮겨봅시다.
먼저, 2번 뷰의 frame을 (0, 0)으로 이동시켜볼게요.
frame은 superview의 좌표시스템 안에서 뷰를 그리기 때문에
3번 뷰는 superview인 2번 뷰의 frame이 변경되었으므로 함께 바뀌게 됩니다.
실제 결과를 출력하면 아래와 같습니다.
1번 뷰
[frame] (20.0, 79.0, 353.0, 719.0)
[bounds] (0.0, 0.0, 353.0, 719.0)
2번 뷰
[frame] (0.0, 0.0, 253.0, 519.0)
[bounds] (0.0, 0.0, 253.0, 519.0)
3번 뷰
[frame] (50.0, 100.0, 153.0, 319.0)
[bounds] (0.0, 0.0, 153.0, 319.0)
그럼 bounds를 옮긴다면 어떻게 될까요 ?
2번 뷰 bounds를 (20, 70)으로 이동시켜볼게요.
흠. . 2번 뷰를 옮겼는데 왜 3번 뷰만 움직일까요 ?
1번 뷰
[frame] (20.0, 79.0, 353.0, 719.0)
[bounds] (0.0, 0.0, 353.0, 719.0)
2번 뷰
[frame] (50.0, 100.0, 253.0, 519.0)
[bounds] (20.0, 70.0, 253.0, 519.0)
3번 뷰
[frame] (50.0, 100.0, 153.0, 319.0)
[bounds] (0.0, 0.0, 153.0, 319.0)
결과를 봐도 bounds는 2번 뷰에 잘 잡혀있고, 3번은 (0, 0)으로 바뀌지 않았습니다.
우리는 "자신만의 좌표 시스템"이라는 점을 간과해선 안됩니다.
bounds는 결국 superview와 아무 관계가 없으므로
bounds를 변경한다는 것은 그냥 그 자리에서 다시 그려진다는 의미가 되는 것이죠.
그렇기 때문에 2번 뷰 자기 자신은 움직이지 않고, 3번 뷰만 움직이는 것처럼 보이는 것입니다.
그럼 이건 언제 필요할까요 ?
ScrollView를 생각해보면 bounds가 필수라는 걸 알 수 있습니다.
스크롤하는 동작 자체가 ScrollView의 bounds를 바꿔주며 어디를 보여줄지 정하는 것이죠.
참고 자료
https://developer.apple.com/documentation/uikit/uiview/1622621-frame
https://developer.apple.com/documentation/uikit/uiview/1622580-bounds
'iOS > iOS' 카테고리의 다른 글
[iOS] URLSession (0) | 2022.09.13 |
---|---|
[iOS] strong / weak / unowned / 순환 참조 (0) | 2022.09.08 |
[iOS] ARC (Automatic Reference Counting) (0) | 2022.09.08 |