본문 바로가기

IOS Swift

Frame과 Bounds의 차이

frame

The frame rectangle, which describes the view’s location and size in its superview’s coordinate system.

superView의 좌표 시스템에서의 뷰의 좌표와 크기를 알려준다. (이때 SuperView는 한 단계 상위 View)

 

bounds

The bounds rectangle, which describes the view’s location and size in its own coordinate system.

자신의 좌표 시스템에서 뷰의 좌표와 크기를 알려준다.

 

Frame과 Bounds는 UIView의 instance property입니다.

근데 위에 보니까 타입이 CGRect?? 그럼 CGRect의 프로퍼티인

origin과 size를 가지고 있겠군요!

일단 한번 print 찍어서 확인해볼까요?? 백문이 불여일견!

보라색 imageView
(x 좌표, y좌표, 가로, 세로)

 

이처럼 Frame은 상위 뷰에서의 나의 View origin 값을 알려줍니다.

Bounds은 나 자신의 좌표계 안에서 나의 View origin 값을 알려주므로 내가 나를 봤을 때 origin은 (0, 0)인 것입니다.

 

뷰를 이동시켰을 때의 차이

Frame을 이동시켰을 때

    func changeFrame() {
        print("--change frame origin--")
        greenView.frame.origin.x = 30
        greenView.frame.origin.y = 30
    }

 

상위 뷰의 좌표계의 origin.x, origin.y를 (30, 30)으로 잘 바뀌었습니다.

 

Bounds를 이동시켰을 때

    func changeBounds() {
        print("--change bounds origin--")
        greenView.bounds.origin.x = 30
        greenView.bounds.origin.y = 30
    }

imageView Bounds = (30 , 30, 171, 127) 입니다. 실수 🥲

 

green bounds를 (30, 30)만큼 옮겼는데 왜 imageView(보라색 뷰)가 움직이냐고 궁금해 할 수도 있는데

왜 이름을 Frame(액자), Bounds(범위)라고 붙인 것일까 생각을 하다가 해결했습니다.

이동시켰을 때 액자는 안에 들어있는 사진이 그대로 보이면서 옮겨지는데 범위 같은 경우 예를 들면 휴대폰 카메라를 다른 곳으로 돌려서 카메라의 범위를 다른곳으로 바꾸면 사진이 보이는 범위가 달리지기 때문에 이름을 이렇게 붙인 것 같습니다.

bounds는 상위의 좌표계와 상관없고 오직 내 좌표계에서 (30, 30) 만큼 더 간 것을 보여줍니다.

이해하기 쉬운 그림을 가져오자면

 

 

이렇게 범위를 옮긴 것입니다.

아니 근데!! CGRect에는 origin 말고 size도 있잖아

size에서의 차이점은 없는 걸까? 실험 고고고

 

Size 변경시켰을 때 차이


Frame Size 변경시켰을 때

    func changeFrameSize() {
        print("--change frame origin--")
        greenView.frame.size.width = 100
        greenView.frame.size.height = 10
    }

imageView x, y 좌표는 원래 205, 43 입니다. 제가 여러가지해보느라 바꿨네요. 변화없다 보시면 됩니다.

저희가 일반적으로 예상한 대로 크기만 잘 줄어드네요.

 

Bounds Size 변경시켰을 때

    func changeBoundsSize() {
        print("--change frame size--")
        greenView.bounds.size.width = 100
        greenView.bounds.size.height = 10
    }

 

 

Frame, Bounds 둘 다 width와 height는 변화가 없이 일치합니다.

차이점으로는 greenView의 Bound Size 변화 시 greenView 자신의 Frame 좌표가 알아서 계산되어 버립니다.

BoundSize 변화시 : greenView frame : (63, 249 , 100, 0) -> (150.5, 384, 100, 10)

  • Frame size를 바꾸면 Frame이든 Bounds든 origin 위치 변경  X
  • Bounds size를 바꾸면 Frame origin 위치 변경 O

 

즉, 우리가 일반적으로 크기를 줄이고 싶다면 Frame Size를 조정하시면 됩니다.

 

회전 시

    func transform() {
        greenView.transform =  CGAffineTransform(rotationAngle: .pi/3)
    }

greenView Frame의 Origin, Size 둘 다 바뀌었네요? 그 이유는 바로

Frame은 UIView를 감싸는 또 다른 사각형이기 때문입니다.

아래 사진을 보면 쉽게 이해할 수 있습니다. 붉은색 네모가 Frame입니다.

 

붉은색 = Frame

이렇게 감싸지는 Frame 범위가 변하게 되므로 greenView의 frame이 변화하게 됩니다.

greenView안에 있는 imageView는 왜 안 변하냐고 물어보면, 당연히 frame은 상위 좌표계에서의 나 자신의 좌표와 크기인데,

회전된 상위 뷰인 greenView에서 그대로 (51, 38) 만 가면 하위 뷰도 그대로 회전 된 점에서 그려지게 됩니다.

 

언제 사용하면 될까?

- Frame :

  • UIView위치나 크기를 설정하는 경우. 

 

- Bounds : 

  • View내부에 그림을 그릴 때 (drawRect).
  • transfomation 후, View의 크기를 알고 싶을 때.
  • 하위 View를 정렬하는 것과 같이 내부적으로 변경하는 경우

 

 

요약

  • Frame은 상위 좌표계 기준, Bounds는 자신의 좌표계 기준으로 origin, size를 결정한다.
  • Bounds의 origin을 변경하면 자신이 아니라 subView가 이동하는 것처럼 보이는 이유는 subView를 그리는 좌표계의 기준이 달라졌기 때문이다.
  • Frame은 UIView를 감싸는 또 다른 사각형이다. ( 회전 시 frame origin, size 둘 다 변경됨)

 

반응형