frame과 bounds의 차이점에 대해 헷갈릴 수도 있으며 면접질문으로 자주 나오기에 한번 정리를 해보겠다
먼저 각각 공식문서를 통해 파악해보자
Frame의 정의는 아래와 같다
The frame rectangle, which describes the view’s location and size in its superview’s coordinate system.
superview의 시점에서의 현재 뷰의 위치와 사이즈에 대해 알려주는 것을 말한다.
frame에서는 superview가 시점인 것을 파악할 수 있다.
frame를 사용할 때에는 보통 사각형을 그릴 때 뷰의 사이즈와 위치를 결정할 때 사용한다.
그러면 frame는 사각형을 그릴 때 사용하는 것이다!
사각형을 그리는 것이므로 x, y, height, width가 필요하다.
draw(_:) 메서드 호출 없이 자동적으로 frame의 사각형을 바꾸기위해 뷰를 다시 보여준다.
만약 frame 사각형이 바뀔 때 UIKit이 draw 메서드를 호출하길 원한다면 contentMode의 프로퍼티를 UIView.ContentMode.redraw로 설정해야한다.
다음으로 Bound의 정의는 아래와 같다
The bounds rectangle, which describes the view’s location and size in its own coordinate system.
자기 자신의 시점에서 자신의 view의 위치와 사이즈를 표현하는 것이다.
기본적인 origin는 (0, 0)이고 사이즈는 frame 프로퍼티에서 사각형의 사이즈와 동일하다.
사각형의 사이즈를 바꾸게 되면 사각형의 중심 점이 상대적으로 늘어나거나 줄어들게 된다.
사이즈를 바꾸니 당연히 프레임 프로퍼티에서 사각형의 사이즈가 변하게 된다. 왜냐하면 상위뷰 기준에서 보았을 때 사각형의 사이즈가 변했으니 프레임 프로퍼티도 변하게 된다.
이제 실제 코드에서 어떤 식으로 보이는지 확인해보는 시간이다!
먼저 뷰는 총 3개가 있을 것이다.
스토리보드로 먼저 아래처럼 그린다! 레이아웃은 딱히 잡을 필요없다
이를 시뮬레이터에서 실행해보면 아래와 같이 그려질 것이다
이제 이것을 이용해서 각 뷰의 Frame, bounds의 좌표가 어떻게 되는지 확인해볼 것이다.
Frame은 말했듯이 자신의 바로 위인 상위뷰의 기준으로 x,y의 좌표가 결정된다.
이제 코드에서 아래와 같이 출력을 해볼 것이다.
print(self.yelloView.frame.origin.x)
print(self.blueView.frame.origin.x)
print(self.blueView.frame.origin.y)
print(self.greenView.frame.origin.x)
print(self.greenView.frame.origin.y)
YelloView는 말했듯이 가장 큰 뷰를 말하고, 그 밑에 BlueView, 그 밑에는 GreenView가 있다.
이제 이를 출력한 결과를 보면 Frame이 어떻게 작동하는지 볼 수 있다.
먼저 YellowView의 상위뷰는 없으므로 0이 나온다.
그리고 blueView의 상위뷰는 YellowView인데, YellowView의 x,y는 (0,0)이다. 이를 기준으로 얼만큼 x,y가 떨어져있는지를 계산해서 출력해준 결과이다.
그래서 x는 48만큼 떨어져 있고 y는 236만큼 떨어져있다는 것을 확인할 수 있다.
이제 GrennView는 쉬울 것이다. 바로 BlueView가 GreenView의 상위뷰이므로 이 기준으로 결과를 내보낸다.
BlueView를 기준으로 x는 28만큼 떨어져있고 y는 42만큼 떨어져있다는 것을 확인가능하다!!!
Frame의 개념은 조금 잡혔을 것이라고 생각한다.
이제 Bounds로 가보도록 하자!
이는 아까 말했듯이 자신 기준의 좌표시스템을 표현한다.
print(self.yelloView.bounds.origin.x)
print(self.blueView.bounds.origin.x)
print(self.greenView.bounds.origin.x)
x만 해보더라도 결과는 뻔히 알 수 있다.
당연히 모두 0이 나올 것이다. y도 마찬가지로 0일 것이다. 왜냐하면 자신 기준이므로 당연히 (0, 0)이 모두 나올 것이다!
이제 각각 개념은 파악했으니 응용 해볼 차례다
blueView.frame.origin.x = self.view.frame.origin.x
blueView.frame.origin.y = self.view.frame.origin.y
이 코드를 입력하면 결과는 어떻게 나올까?
결과는 매우 간단하다 바로 self.view.frame.origin.x 와 y는 (0.0)이므로 이 위치로 가질 것이다.
이는 아래의 그림보면 결과가 어떻게 나오는지 알 수 있다.
이제 bounds를 응용해보도록 하자
blueView.bounds.origin.x = 30
이것을 넣으면 어떻게 나올까?
바로 아래처럼 나오 것을 확인할 수 있다.
왜??
나는 blueView를 바꾸었는데 왜 greenView가 이동한 것처럼 보일까?
원래 위치는 48이 띄어져있었다. 근데 30으로 줄였는데 이는 bounds의 속성을 파악해보면 된다.
bounds는 자신의 좌표 시스템을 기준으로 이동한다. 그래서 새로 좌표시스템을 변경하는 것을 받고 이를 다시 그려주게된다.
다시그려야만 원하는 위치로 가겠죠?
그런데 이렇게 이동하는 과정이 마치 내부에 있는 GreenView가 이동한 것처럼 보이는 것이다.
그러나 실제로 본다면 GreenView는 가만히 있고 BlueView의 bounds가 조정되며 다시 그려진 것이다.
이제 1탄으로 정의와 간단한 예시를 넣었다!
2탄에서는 조금 더 심화된 내용을 정리해서 올려볼 것이다.
참고 사이트
https://developer.apple.com/documentation/uikit/uiview/1622621-frame
https://developer.apple.com/documentation/uikit/uiview/1622580-bounds