본문 바로가기

코딩의 유익함/스위프트(Swift)

SwiftUI - GeometryReader(지오메트리 리더)

그림1) GeometryReader

GeometryReader는 SwiftUI에서 제공하는 여러 컨테이너 뷰 중의 하나이며, 자식 뷰에게 부모 뷰와 기기에 대한 전반적인 정보를 전달하는 역할을 합니다. 먼저 그 정의부터 살펴보고 내용을 하나씩 알아보도록 하겠습니다.

 

그림2) GeometryReader

GeometryReader 구조체는 View 프로토콜을 채택하고 있습니다. 그리고 제네릭으로 선언된 Content 역시 반드시 View 프로토콜을 채택해야만 한다고 강제하고 있습니다.

 

content 프로퍼티는 그 타입이 클로저(함수 형태)인데요. 풀어서 GeometryProxy 타입의 인자를 1개 받아서 Content 타입(뷰 프로토콜을 채택하는)을 반환하는 클로저 타입입니다.

 

생성자에는 content 매개변수에 @ViewBuilder 속성이 선언되어 있으므로, 뷰를 전달받아 하나 이상의 자식 뷰를 만들어 낼 수 있는 즉, content에 뷰를 나열하는 것만으로도 컨테이너 뷰를 만들 수 있습니다.

 

위에서 설명하지 않은 GeometryProxy은 무엇일까요? 역시 타입의 정의부터 살펴보겠습니다.

 

그림3) GeometryReader

먼저 size 프로퍼티는 GeometryReader 뷰가 차지하는 크기를 반환하는데, 넓이와 높이 등을 숫자 값으로 확인할 수 있습니다. 부모 뷰일 경우 기기마다 다른 높이와 넓이 값을 알 수 있어 매우 유용합니다.

 

safeAreaInsets 프로퍼티는 GeometryReader가 사용된 환경에서 안전 영역의 크기를 반환합니다. 기기별 그 크기가  의도치 않게 지정한 영역을 벗어나는 것을 방지할 수 있습니다.

 

frame은 특정 좌표계를 기준으로 한 프레임 정보를 반환하는데, coordinateSpace의 타입의 형태를 인자로 받고 있습니다. 그림4)에서 타입 정의를 살펴니 3개의 case로 이루어져 있습니다.

 

여기서 local은 GeometryReader를 기준으로 한 좌표, global은 기기의 화면 전체 영역을 기준으로 한 좌표, named는 이름이 붙여진 뷰를 기준으로 한 좌표를 반환합니다. 아래에서 자세히 살펴보겠습니다.

그림4) GeometryReader

subscript는 여기서 모두 설명하기에는 어려움이 있어 따로 포스팅을 하겠습니다. 먼저 size와 safeAreaInsets을 적용한 코드를 살펴보겠습니다.

 

그림5) GeometryReader

먼저 위 예제는 책 "스윗한 SwiftUI"을 참조해서 작성한 것임을 말씀드립니다. 빨간 박스들을 보시면 GeometryProxy 타입의 geometry 변수를 통해서 컨테이너 뷰의 넓이와 높이를 가져올 수 있습니다.

 

가져온 넓이와 높이를 임의의 숫자로 나누어주면 그 비율대로 간격이 조절되고, 기기가 바뀌더라도 해당 비율은 유지될 것이기에 기기별 코드 작성을 하지 않아도 됩니다.

 

프리뷰의 네모 박스 크기가 GeometryReader의 크기이며, 그 값을 출력하고 있습니다. safeAreaInsets을 통하면 기기 별로 위, 아래 등의 안전 영역을 알 수 있고, 이를 이용하면 뷰가 기기 밖을 벗어나지 않겠지요.

 

다음은 frame 함수를 적용한 코드를 살펴보겠습니다.

 

그림6) GeometryReader

GeometryReader 뷰에서 선언한 3개의 프로퍼티는 GeometryProxy 타입인 gemetry에서 frame함수를 호출하면서 인자로 coordinateSpace 타입에 속한 값을 전달하고 있습니다.

 

여기서 반환 값이 CGRect 구조체 타입입니다. 그래서 내부에 존재하는 CGPoint 좌표 타입의 프로퍼티 origin의 값을 가져와서 아래의 Text 뷰로 출력을 한 결과를 프리뷰에서 확인할 수 있습니다.

 

local은 GeometryReader 자신을 기준으로 한 좌표이기에 (0, 0)이 나옵니다. global은 기기 화면 전체 영역을 기준으로 x는 166만큼, y는 47만큼 떨어진 곳에 GeometryReader 뷰가 있습니다.

 

named는 Hstack의 이름으로서 노란색 왼쪽 상단의 좌표로부터 x는 166만큼, y는 0만큼 떨어진 곳에 GeometryReader 가 있음을 확인할 수 있습니다.

 

공부하면서 작성한 내용이므로 오류가 있다면 양해 부탁드립니다.