본문 바로가기

ios

10. ios의 frame과 bounds

Frame

  • 정의
    • 부모 뷰의 좌표계에서의 뷰의 위치와 크기를 나타낸다.
  • 구성요소
    • frame은 origin(x,y)와 size(너비, 높이)를 포함한다.
  • 좌표 단위
    • frame의 좌표는 항상 points단위로 지정된다.
    • 화면의 픽셀이 아닌, 화면 해상도와 관련 없이 화면 요소의 상대적 위치를 나타낸다.
  • center와 bounds의 자동 변경
    • center
      • frame을 설정하면 center 속성이 변경됩니다.
      • center는 뷰의 중심위치를 나타내는 데, frame을 변경하면 이 값도 자동으로 업데이트 됩니다.
    • bounds
      • bounds는 뷰의 크기를 나타내는 속성
      • frame의 크기를 변경하면 bounds의 크기도 함께 조정된다.
      • bounds는 뷰의 내부 크기를 의미한다.
      • frame의 크기를 변경해도 뷰의 내용(자식뷰들)에 영향을 미치지 않지만, 뷰의 표시 영역은 영향을 받는다.
  • 사용 목적
    • frame은 뷰의 레이아웃 작업 중에 뷰의 크기와 위치를 설정하는데 사용된다.
      • Q. 레이아웃 작업이 끝난 상황에서는 frame 수정이 반영되지 않는 건가?
      •  
  • 사용법
    • 뷰를 부모 뷰의 좌표계에 상대적으로 배치하거나 크기를 조정할 때 사용됩니다. 
    • 예를 들어, 다른 뷰들과의 상대적인 위치를 설정할 때 frame을 사용한다.
  • 자동 리디스플레이
    • frame을 수정하면 뷰가 자동으로 다시 표시(리디스플레이)되지만, draw(_:) 메서드는 호출되지 않습니다. 즉, 뷰의 크기나 위치가 변경되어도 화면에 즉시 반영되지만, 화면을 다시 그리지는 않습니다.
    • 만약 뷰를 다시 그려야 한다면 **setNeedsDisplay()**나 **contentMode.redraw**를 사용해야 합니다.
    • frame을 수동으로 변경할 경우에는 뷰의 위치크기가 변경되지만, 레이아웃 시스템이 자동으로 이를 반영하지는 않습니다. 수동으로 변경한 값은 레이아웃 시스템에 의해 다시 계산되지 않습니다.
    • 예를 들어, **자동 레이아웃(auto layout)**을 사용하고 있을 경우, frame을 직접 변경하는 것보다는 제약 조건을 변경하는 것이 더 적절합니다. frame을 수동으로 수정하면 자동 레이아웃 제약조건에 의해 다시 덮어씌워질 수 있습니다.
    • frame을 직접 변경하면, 자동 레이아웃 시스템은 여전히 제약 조건을 우선시하며, **frame**이 자동 레이아웃 제약 조건에 의해 덮어씌워질 수 있습니다. 예를 들어, frame을 변경한 후 layoutSubviews() 또는 자동 레이아웃 업데이트가 실행되면, frame 값은 제약 조건에 의해 재계산되고 다시 원래 상태로 돌아올 수 있습니다.
    • 만약 뷰가 시각적으로 다시 그려지길 원한다면, contentMode를 **UIView.ContentMode.redraw**로 설정하거나, **setNeedsDisplay()**를 호출해 뷰를 강제로 다시 그리도록 해야 합니다.
      • Q. 위치와 크기는 바뀌었지만 사용자 눈에는 안보이는 건가?
  • transform 속성 사용시 주의
    • transform 속성이 단위 행렬이 아닌 경우, frame의 속성의 값은 정의 되지 않으며 이 값을 수정해서는 안된다.
    • 이 경우, center 속성을 사용해 뷰의 위치를 조정하고, bounds 속성을 사용해 크기를 조정하는 것이 좋다.
      • Q.transform 속성이 뭐야?
        • 뷰의 회전, 크기 조정, 기울임등의 변형을 다루는 속성이다.
      • 단위행렬(identity transform)
        • 단위행렬은 변형이 적용되지 않은 상태를 나타냄
        • 즉, 뷰에 아무런 변형도 없을 때 frame을 제대로 계산하고 수정할 수 있다.
      • transform이 단위 행렬이 아닌 경우, frame 속성은 뷰의 변형된 상태를 반영할 수 없게 됩니다. 즉, 회전이나 확대/축소된 뷰의 실제 크기와 위치는 frame을 사용하여 계산할 수 없게 됩니다.
        • 예를 들어, 회전된 뷰의 **frame**은 실제 뷰가 화면에서 차지하는 공간을 정확하게 나타내지 않게 되며, 변형된 상태에서는 **frame**이 정확하지 않기 때문에 이 값을 수정하면 안 됩니다.
      • center와 bounds를 사용해야하는 이유
        • center
          • 뷰의 중심을 나타내며, 뷰의 위치를 조정할 때 **변형(transform)**과 관계없이 중심 좌표만으로 위치를 쉽게 변경할 수 있습니다.
          • transform이 적용된 뷰의 위치를 바꾸려면 **center**를 사용하여 중심 위치를 직접 지정하는 것이 더 안전하고 정확합니다.
        • bounds:
          • **bounds**는 뷰의 크기를 정의하는 속성입니다. **transform**을 적용한 후 크기 변경을 하고 싶다면, bounds를 사용하여 뷰의 내부 크기를 조정합니다.
          • transform은 뷰의 내부 좌표 시스템에 영향을 미치므로, **frame**을 수정하는 것보다는 **bounds**를 사용하여 뷰의 크기를 변경하는 것이 더 안전합니다.
  • frame 변경 시 자동 리디스플레이:
    • frame을 변경하면 뷰가 자동으로 다시 그려지지 않고 화면에 즉시 표시됩니다. draw(_:) 메서드를 호출하여 다시 그리기를 원한다면, contentMode 속성을 **UIView.ContentMode.redraw**로 설정해야 합니다.
  • 애니메이션:
    • frame 속성은 애니메이션을 통해 변경될 수 있습니다. 하지만 transform 속성이 단위 행렬이 아닐 경우, frame은 수정할 수 없으므로 center와 bounds를 사용해 애니메이션을 적용해야 합니다.

Bounds

  • 정의
    • 뷰의 자체 좌표계에서의 크기와 위치를 나타낸다.
  • 구성요소
    • size, origin
  • 사용법
    • bounds는 뷰 내부에서의 상대적인 위치나 크기를 조정하는데 사용된다.
    • 뷰 내부의 콘텐츠 레이아웃을 설정하거나, 스크롤 뷰의 스크롤 영역을 정의할 때 bounds가 사용된다.

 

차이점

  • 좌표계
    • 가장 큰 파이점은 좌표계에 있다.
    • frame은 부모 뷰에 대한 좌표계를 사용하고 bounds는 뷰 자체의 좌표계를 사용한다.
  • 변형(transform)
    • frame은 뷰에 변형(회전, 스케일링 등)이 적용된 후 제대로 된 크기나 위치가 변경되어있다.
    • bounds는 뷰의 내부 좌표계에서 항상 일관되게 유지된다.

'ios' 카테고리의 다른 글

12. Clean Architecture (iOS)  (0) 2023.12.24
11. 동기화 공부하기  (0) 2023.12.13
9. Files owner를 이해보자  (0) 2023.12.10
8. Xcode button의 Sent Events에 대해서 알아보자  (0) 2023.12.04
7. iOS UIApplication 공부하기  (0) 2023.11.21