iOS

[Swift] Bounds와 Frame에 대해 알아보자

하이D:) 2023. 11. 18. 16:40

길고도 험난했던 "Bounds와 Frame의 차이"에 대한 이해의 길..

소들이님 블로그를 보고 어느 정도 설명할 수 있을 만큼 이해하게 되어 기록을 남기려 합니다.

 

우리가 UIView를 그릴 때 생성자로도 많이 접했지만 그냥 넘겨왔던.. frame..

var uiView : UIView! = .init(frame: CGRect(x: 50, y: 50, width: 200, height: 200))

 

스크롤 뷰 구현할 때 어렴풋이 본 것 같은 bounds라는 개념들..

 

처음 공부를 시작할 때 쉽지 않겠다고 생각한 만큼 이해하는데 생각보다 많은 시간이 필요했지만 이해하니까 또 그만큼 보이는 것 같아요. 아는 만큼 보이는 걸 실감할 때마다 공부를 더 많이 해야겠다고 다짐합니다 ㅎㅎㅎ

 

 

# 🥨 Bounds와 Frame

일단 Bounds와 Frame는 UIView 내의 프로퍼티로서 CGRect 타입이며, view의 위치와 크기를 나타내는데요.
차이를 알아보자면 이렇습니다..

 

superview 좌표계에서의 위치와 사이즈를 나타낸다.

예를 들어, 스크린 전체를 기준으로 특정 뷰가 (100, 200)의 좌표에 크기가 50x50인 경우, 해당 뷰의 frame은 {100, 200, 50, 50}이다.

 

그렇다면 superview란 무엇일까요?

superview란 ViewController의 계층 구조에서 내 view의 "한 칸" 윗 계층에 있는 View를 말하는데요

최상위 view가 아니라 나의 한 칸! 윗 계층 view를 말하는 것임을 주의해야 한다!

 

 

자기 자신의 좌표계에서 위치와 사이즈를 나타낸다.

대부분의 경우 bounds의 원점(origin)은 항상 (0, 0)이며, 크기는 뷰의 폭과 높이를 나타냅니다.
예를 들어, 뷰의 크기가 50x50이면 bounds는 {0, 0, 50, 50}입니다.

 

 

하나도 이해가 가지 않죠?? 좀 더 자세하게 차근차근 알아봅시다!!

 

 

# 🥨  Frame의 origin과 size

Frame의 origin

슈퍼뷰의 원점(가장 왼쪽 & 가장 위의 점)을 (0,0)으로 놓고 원점으로부터 얼마나 떨어져 있는지를 나타낸 것

예를 들어 이렇게요!

 

만약 위처럼 단순한 화면이 아니라 UIView가 여러 계층으로 쌓여있다면 어떻게 될까요?

한 단계씩 높은 계층의 view를 기준으로 삼게 되는 것이죠! (앞서 설명했던 슈퍼뷰를 기준으로 삼는 것입니다!)

 

 

 

Frame의 size

처음에 찾아봤을 때는 '슈퍼뷰에서 차지하고 있는 크기'라고 해서 오히려 이해하기 어려웠는데요. '본인 view 영역을 모두 감싸는 사각형의 크기'라고 이해하니 훨씬 이해가 잘 됐습니다.

 

왜 이렇게 이해해야 하냐?!

뷰의 회전 개념이 나오면 왜 그런지 이해할 수 있는데요

 

우리가 정의한 버튼의 크기가 width 100, height 50이라고 할 때 

 

회전을 해서 frame.size 값을 확인해 보면 값이 달라져있습니다.

이게 바로 frame.size는 뷰 자체의 크기가 아니라 '뷰룰 감싸고 있는 사각형의 크기'를 나타내기 때문입니다.!

 

 

 

# 🥨  Bounds의 origin과 size

Bounds의 origin

어떤 뷰에서 bounds의 origin이라는 것은 슈퍼뷰와 관련 있었던 frame과는 다르게!  슈퍼뷰와는 관련 없이 그냥 본인 기준의 위치를 나타내는 것입니다.

즉, 자기 자신의 원점(가장 왼쪽&가장 위의 점)을시작점(0,0)으로 놓는 것이죠. 그러니 특별한 경우가 아니면 bounds의 origin은 (0,0)일 수밖에 없겠죠?

 

 

Bounds의 size

frame의 size와 다르게 자기 자신 뷰의 크기만 나타낸 것입니다. frame의 size는 뷰가 회전하면 변화할 수도 있다고 말씀드렸죠?

하지만, bounds의 size는 본인 자체의 크기를 나타내기 때문에 뷰가 회전해도 width와 height가 변하지 않는 것입니다.

 

 

# 🥨 UIView가 여러 계층으로 쌓여있는 경우 Frame, Bounds의 origin 값을 바꾸면?

여러 겹의 뷰에서 frame의 origin을 바꾸면?

view2.frame.origin = CGPoint(x: 50, y: 100)

결론을 말씀드리자면 해당 뷰는 당연히 슈퍼뷰의 원점으로부터 할당한 origin 값만큼 움직이고, SubView도 그만큼 같이 움직인다는 것입니다. frame 은 한 단계 윗 뷰인 슈퍼뷰의 원점(0,0)을 기준으로 가지기 때문인데요.


아래 그림에서 view3는 한 단계 위의 슈퍼뷰인 view2 기준으로 움직이기 때문에 view2의 움직임에 같이 움직여진 것이죠!

 

 

 

여러 겹의 뷰에서 bounds의 origin을 바꾸면?

frame에서는 값을 바꾸면 슈퍼뷰를 기준으로 위치가 변경되었는데 bounds의 origin은 그리 만만(?)하지 않습니다.. 

bounds의 origin 값을 바꾸면 viewport가 변경된다고 했는데 이게 처음에는 너무 이해가 가지 않았습니다.
    
한 문장으로 정리하자면 “viewport가 이동한다”인데 저는 이 뷰포트 이해하기 넘 어려웠습니다.

화면에 여러 뷰들이 그려져 있는데 이때 우리 눈에 보이는 (화면상에 나와있는) 뷰들이 있죠? 이 부분을 뷰포트라고 한답니다!
    
쉽게 예를 들자면 우리는 스크롤 뷰를 많이 사용하잖아요? 이 때 우리가 보는 화면 밖에 그려져 있는 뷰들이 많죠? 안 보이는 뷰들은 우리가 스크롤 동작을 하면 비로소 안 보였던 뷰들이 위로 올라오거나 혹은 아래로 내려가면서 화면에 보이잖아요!

뷰포트는 이런 개념이라고 생각하시면 됩니다!

 

헉헉 이 개념 하나도 어려오..

 

 

일단 본론으로 돌아와서 UIView가 여러 계층으로 쌓여있을 때 bounds의 origin값을 바꾸는 상황을 보겠습니다.

view2.bounds.origin = CGPoint(x: 50, y: 10)

이 코드처럼 view2의 bounds.origin를 바꾸면 view2의 영역이 하나의 viewport가 되고, 그 뷰포트가 origin에 할당한 값만큼 이동했을 때 보이는 서브뷰 만큼이 뷰에 반영되는 것입니다.

이렇게 글로 설명하게 이해 불가죠? ㅎㅎ

 

1. 일단 앞에서 봤다싶히 모든 뷰에서의 bounds.origin은 일단 (0,0)으로 초기화되어 있습니다.

 

 

2. view2의 bounds.origin값을 바꾸면 일단 view2 영역이 하나의 viewport가 됩니다.

 

 

3. 그리고 이 viewport가 이동하죠

 

 

4. viewport가 이동해서 보이는 하위뷰가 반영됩니다.

 

 

조금.. 이해가 되셨나요?? bounds의 origin은 일단 viewport 개념만 이해해도 반은 완성인 것 같아요 ㅎㅎ

 

 

# 🥨 그럼 Bounds와 Frame은 각각 언제 사용해야 하나..

Frame

일단 Frame은 앞서 본 것처럼 개념이 어렵지 않고 슈퍼뷰 개념만 이해했다면 직관적으로 이해할 수 있기 때문에 사용할 때도 어렵지 않을 것 같아요. 

Frame은 슈퍼뷰 내의 본인 위치를 알고 싶을 때 혹은 뷰를 그릴 때 UIView의 위치 및 크기를 설정할 때 사용합니다.

 

Bounds

- 뷰가 회전했거나 변형이 있을 때 실제 너비, 높이를 알고 싶을 때

앞서 본 것처럼 Frame의 size은 본인 뷰를 감싸고 있는 사각형의 너비, 높이 이기 때문에 뷰가 회전했을 때 width, height 값이 바뀌지만 Bounds의 size는 본인 뷰의 크기를 나타내기 때문에 뷰가 회전했을 때에도 width, height 값이 바뀌지 않기 때문에 실제 너비, 높이를 알고 싶을 때 유용하겠네요!

 

- 스크롤을 사용할 때

Bounds의 origin 값을 변경해 줄 때 뷰포트가 변경된다는 것을 앞서 설명했는데요. 이 개념을 응용하여 적용한 게 바로 스크롤뷰에서의 스크롤입니다!

우리가 손가락으로 스크롤하는 동작이 바로!! ScrollView의 bounds의 origin 변경해 주는 것! 즉, 스크롤 동작을함으로써 스크롤뷰의 뷰포트를 다르게 바꿔주어서 보이는 화면 밖에 존재하는 뷰를 화면상에 보여주는 것입니다~~!!

 


 

험난했던 Frame과 Bounds 개념의 이해..

진짜 알고 보면 별거 아닌데 알아가는 과정은 왜 이렇게 어려울까요 ㅠㅠ 공부할 때면 내가 바보인가 싶어서 현타가 오더라도 이해하고 나서의 쾌감을 잃지 못해 계속 공부를 하는 것 같습니다 ㅎㅎ

 

 

이해하는데 많은 도움이 되었던 블로그입니다!

iOS) Frame vs Bounds 제대로 이해하기 (1/3)