UIKit: Frame과 Bounds 2
UIKit: Frame과 Bounds 1 UIKit: Frame과 Bounds 1UIKit으로 UI를 그리다 보면 심심찮게 보이는Frame과 Bounds 막상 사용해보면 큰 차이를 못 느낀다...공식 문서를 살펴보면FrameThe frame rectangle,which describes the view’
dev-arthur.tistory.com
지난 글에 이어서
이번 마지막 글에서는
Bounds의 Origin에 대해 알아보려고 한다.
self.view.backgroundColor = .green
self.view.addSubview(self.childView)
self.childView.backgroundColor = .yellow
self.childView.frame.size = .init(width: 100, height: 100)
self.childView.center = self.view.center
let boundsLayer = CAShapeLayer()
boundsLayer.path = UIBezierPath(rect: childView.bounds).cgPath
boundsLayer.strokeColor = UIColor.blue.cgColor
boundsLayer.lineWidth = 3
boundsLayer.fillColor = UIColor.clear.cgColor
boundsLayer.lineDashPattern = [6, 6]
self.childView.layer.addSublayer(boundsLayer)
Origin을 수정하지 않은 상태에서 Bounds
위 코드에 Origin을 수정하는 코드를 추가하면
self.childView.bounds.origin = .init(x: 50, y: 50)
뷰는 그대로지만, 뷰의 Bounds를 그대로 본뜬 Layer는 좌측 상단으로 이동했다.
잘 이해가지 않아서
Origin 수정 후, 뷰의 Bounds를 그대로 본뜬 Layer를 추가적으로 다시 그려봤다
음...
Bounds 값을 출력해 보면 분명 Origin 값이 변경된 것은 맞으나
뷰 자체에는 영향이 없고, 뷰의 Bounds 형태를 확인하기 위해
뷰의 하위 뷰에 넣은 layer의 위치만 변경되고 있다.
여전히 이해가 되지 않아서, 공식 문서를 살펴보다가
다음과 같은 문장을 발견했다.
The frame property contains the frame rectangle,
which specifies the size and location of the view in its
superview’s coordinate system.
The bounds property contains the bounds rectangle,
which specifies the size of the view (and its content origin) in the view’s own local coordinate system.
frame 프로퍼티는 부모뷰 좌표계에서 뷰의 크기와 위치를 지정하는 사각형 틀을 포함한다.
bounds 프로퍼티는 뷰 자신의 좌표계에서 뷰의 크기(그리고 뷰의 콘텐츠 좌표)를 지정하는 사각형 경계를 포함한다.
이전 1번 글에서 본 내용 아냐?라고 생각할 수 있지만,
여기서 주의 깊게 봐야 하는 부분은
'그리고 뷰의 콘텐츠 좌표'라는 부분이다.
frame과 달리, bounds는 뷰의 콘텐츠 좌표라는 표현을 썼다.
즉, bounds의 origin 값은 뷰의 위치를 지정하는 것이 아닌,
뷰 내부의 콘텐츠의 위치를 지정하는 데 사용된다는 것을 알 수 있다.
그리고 추가적으로, 아래 내용이 그 사실을 뒷받침해 준다.
Anything you draw inside this rectangle is part of the view’s visible content.
If you change the origin of the bounds rectangle,
anything you draw inside the new rectangle becomes part of the view’s visible content.
이 사각형(Bounds Rectangle) 안에 그리는 모든 것들은 뷰의 보이는 콘텐츠의 일부이다.
만약 사각형 경계의 origin을 바꾼다면, 새로운 사각형 안에 그리는 모든 것들은 뷰의 보이는 콘텐츠의 일부가 된다.
예를 들어서
self.childView.addSubview(self.imageView)
self.childView.addSubview(self.imageView2)
self.childView.backgroundColor = .yellow
self.childView.frame.size = .init(width: 200, height: 200)
self.imageView.frame = .init(x: 0, y: 0, width: 100, height: 100)
self.imageView2.frame = .init(x: 100, y: 100, width: 100, height: 100)
노란색 뷰에 2개의 이미지뷰를 하위뷰로 추가했을 때,
노란색 뷰의 Bounds의 Origin을 수정했다.
self.childView.bounds.origin = .init(x: 100, y: 100)
좌측 상단 이미지 뷰의 Frame의 Orgin은 (0, 0)
우측 하단 이미지 뷰의 Frame의 Orgin은 (100, 100)
두 개의 이미지 뷰는 노란색 뷰의 자식뷰이니까,
즉, 두 개의 이미지 뷰의 Frame의 Orgin은 노란색 뷰 안에서 어디에 위치시킬 것인가를
설정하는 코드!
노란색 뷰의 Bounds의 Orgin을 (100, 100)으로 바꾼다는 것은
노란색 뷰의 콘텐츠 즉, 자식 뷰들을 보여주는 기준을 (100, 100)으로 바꾼다는 것!
(UIKit에서 원점(기준) 좌표는 좌측 상단)
즉, 노란색 뷰 내부에서 자식 뷰들을 배치시키는 좌표계의 기준(좌측 상단)이 (100, 100)으로 바뀐다!
그렇기 때문에,
그 바뀐 기준으로 자식 뷰들의 위치도 바뀌게 되고
결과적으로, 위 사진처럼 이미지 뷰들의 위치가 바뀌어서 보이게 된다!
그리고!
이것은 마치,
뷰의 위치는 움직이지 않지만, 콘텐츠(자식 뷰)들의 위치 바뀌는
ScrollView와 같은 것을 생각해볼 수 있다!
Bounds의 Origin은 ScrollView처럼 뷰의 콘텐츠들의 위치를 이동시켜야 하는 상황에서 사용하는 좌표값이다.
그래서 진짜 마지막으로, Frame과 Bounds에 대해 간단하게 정리해 보자면!
Frame | Bounds | |
Size | 부모 뷰 기준에서 해당 뷰의 사각형을 감싸는 사각형의 크기 |
해당 뷰 자체의 사각형의 크기 |
Origin | 부모 뷰 기준에서 해당 뷰의 위치 |
해당 뷰의 콘텐츠(자식 뷰)를 보여줄 기준 위치 |
'iOS' 카테고리의 다른 글
Swift: @retroactive (0) | 2025.05.31 |
---|---|
SwiftUI: @ViewBuilder (0) | 2025.04.16 |
UIKit: Frame과 Bounds 2 (0) | 2025.01.10 |
UIKit: Frame과 Bounds 1 (0) | 2025.01.05 |
Xcode: 영역 (0) | 2025.01.01 |