Frame 과 Bounds의 차이

zeke·2021년 7월 4일
2

UIKit

목록 보기
4/8
post-thumbnail

UIView를 다루면서 흔히 볼 수 있는 속성 2가지, frame과 bounds 이 둘의 차이점은 무엇일까??

우선 UIView의 애플공식문서부터 찾아보았습니다.


UIView의 설명 중 Animations섹터에 frame과 bounds의 언급이 있어 읽어보았습니다.

1. UIView의 Animations

뷰가 갖고있는 속성들 중 몇가지를 변경하면 현재 value에서 시작하여 새 value로 끝나는 애니메이션을 만들 수 있습니다.
그 속성들은 다음과 같습니다.

  • frame
  • bounds
  • center
  • transform
  • alpha
  • backgroundColor

UIViewPropertyAnimator객체를 만들고 이 객체의 handler block을 사용하여 속성 value을 변경합니다. 그러면 변경 사항에 대한 애니메이션을 적용할 수 있습니다.
UIViewPropertyAnimator 클래스는 애니메이션의 시간과 타이밍을 정할 수 있게 해줍니다.


frame과 bounds 속성을 이용하여 애니메이션을 만들 수 있다는것은 알았습니다. 하지만 frame과 bounds의 차이에 대해 구체적인 정보는 얻지 못했으므로 이어서 frame과 bounds를 각각 애플 공식문서로 찾아보았습니다.



2. Frame

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

frame은 superview의 좌표계에서 view의 위치와 사이즈를 설명하는것이라고 합니다.
여기서 핵심은 superview와 view의 연관성인 것 같습니다.

2-1. Declaration

var frame: CGRect { get set }

2-2. Discussion

  • frame은 superview의 좌표계에서 뷰의 크기와 위치를 정의합니다. 레이아웃 작업 중 이 frame을 사용하여 view의 size와 loaction을 설정 할 수 있습니다.
  • size와 location을 설정하면 center속성이 변경되고 그에따라 bounds사각형의 size가 변경됩니다.
  • frame사각형의 좌표는 항상 point단위로 지정됩니다.

Discussion중간에 warning이 아주 새빨갛고 무섭게 표시되어있습니다. 내용은 다음과 같습니다.

Warning

If the transform property is not the identity transform, the value of this property is undefined and therefore should be ignored.

transform의 속성이 identity transform이 아니라면 이 속성의 value는 정의되지 않았습니다.
그러므로 꼭 무시해야합니다.(identity transform이 아니라면 transform 속성을 사용하지 마세요라고 말하는 것 같아요.)

이어서 frame에 대해 설명하겠습니다.

  • frame을 변경하면 draw(_: )메소드를 호출하지 않아도 view가 자동으로 다시 표시됩니다.
  • 만약 frame을 변경할 때 draw(_: )메소드를 호출하도록하려면 contendMode 속성을 UIView.ContentMode.redraw로 설정해야 합니다.
  • 이 속성에 대한 변경 사항은 애니메이션 될 수 있습니다. 하지만 transform속성이 non-identity transform상태이면, frame의 value는 정의되지 않으며 수정해서는 안됩니다. 이 경우에는 center속성을 사용하여 뷰를 재배치하고 bounds속성을 사용하여 크기를 조정해야 합니다.

바로 이어서 bounds를 알아보려고 했지만, transform이 자주 언급되어 먼저 찾아보았습니다.




3. transform

Specifies the transform applied to the view, relative to the center of its bounds.

bounds의 center와 관련하여 뷰에 적용된 transform을 지정하는 프로퍼티인가 봅니다.

3-1. Declaration

var transform: CGAffineTransform { get set }

3-2. Discussion

  • transform속성을 이용하여 수퍼 뷰의 좌표계 내에서 view의 사각형을 회전합니다.(view의 position을 변경하려면 center속성을 수정해야 합니다.)
  • 이 속성의 default값은 CGAffineTransformIdentity 입니다.
  • 변환은 view의 anchor point를 기준으로 발생합니다. 기본적으로 anchor point는 frame의 center point와 같습니다.
  • anchor point를 변경하려면 view에 내재되어있는 CALayer객체의 anchorPoint속성을 수정해야 합니다.
  • transform속성의 변화를 애니메이션 할 수 있습니다.
  • iOS 8.0 이상 버전에서는 transform속성이 오토레이아웃에 영향을 주지 않습니다. 오토레이아웃은 변형되지않은 프레임(untransformed frame)을 기준으로 view의 alignment를 계산합니다.

Warning

When the value of this property is anything other than the identity transform, the value in the frame property is undefined and should be ignored.

이 속성의 값이 identity transform이 아닐 경우, frame속성 안에 있는 값은 정의되지 않았으므로 무시되어야 한다.
frame에서 나온 경고와 내용이 같습니다.




4. Bounds

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

bounds는 좌표계에서 view의 위치와 크기를 설명합니다. frame과 다른점은 superview와의 연관성 없이 그 자체의 좌표계에서 위치와 크기를 나타내는 것 같습니다.

4-1. Declaration

var bounds: CGRect { get set }

4-2. Discussion

  • 기본 bounds의 origin은 (0,0)이고 size는 frame속성의 size와 같습니다.
  • 이 bounds의 size를 변경하면 center point을 기준으로 view가 늘어나거나 줄어듭니다.
  • bounds의 size를 변경하는것은 frame속성의 size 또한 변경됩니다.
  • bounds의 좌표계는 항상 points로 정해집니다. (단위를 말하는 것 같습니다.)
  • frame과 마찬가지로 bounds를 변경하면 draw(_:)메소드를 호출하지 않고도 자동으로 view가 다시 표시됩니다.
  • frame과 마찬가지로 draw(_:)메소드를 호출하도록 하려면 contentMode속성을 UIView.ContentMode.redraw로 설정합니다.
  • bounds속성을 변경하는것은 애니메이션 될 수 있습니다.



5. 요약

간단히 말해서 view의 bounds는 자신의 공간에 상대적인 좌표를 참조하고 frame은 상위 공간에 상대적인 좌표를 참조합니다.

이것은 다음을 의미합니다.

  • X: 0, Y: 0, width: 100, height: 100로 view를 만들면 이 view의 frame과 bounds는 같습니다.
  • 이 view를 X: 100으로 이동하면 frame에는 변경사항이 저장되지만 bounds에는 저장되지 않습니다. 기억해야할 것은, bounds는 view의 자체 공간에 상대적이고 view내부적으로는 아무것도 변경되지 않았습니다.
  • view를 회전하거나 늘리는것 처럼 변환하는 경우, frame은 이를 반영하여 변경되지만 bounds는 변경되지 않습니다.

frame이나 bounds의 width 혹은 height를 변경하면 다른 값도 이에맞게 업데이트 됩니다.
따라서, 일반적으로 bounds와 center 그리고 transform을 변경하고 UIKit이 알아서 frame을 계산하도록 하는것이 좋습니다.

profile
iOS & Swift

1개의 댓글

comment-user-thumbnail
2021년 7월 4일

Frame과 Bound의 차이를 잘 알겠네요! 도움이 되었습니다.😊

답글 달기