Stacks, Grids, and Outlines in SwiftUI

링크

SwiftUI은 기본 레이아웃 요소들은 Compositional 하게 사용 되도록 설계되었다. 이들 각각을 사용, 조합하여 원하는 레이아웃을 구성할 수 있다.

Stacks

우린 VStackHStack의 조합으로 아래와 같은 갤러리 레이아웃을 구성할 수 있다. 그리고 이들 Stack만으로는 스크롤이 불가능하기 때문에 ScrollView 안에 이들을 구성하였다.

하지만 갤러리 이미지가 많아질수록 그 모든 이미지를 한 번에 불러오는 데 있어 문제가 발생한다. 이는 반응성을 저해하는 요소가 될 수 있다.

이를 위해 Lazy 하게 컨텐츠를 불러올 수 있는, 즉 처음 랜더링될 때 필요한 컨텐츠만 불러오고 이후 필요할 때 나머지를 컨텐츠를 불러올 수 있는 LazyVStackLazyHStack이 새로 생겼다.

이들을 통해 메모리 공간이 불필요하게 커지는 것을 방지할 수 있다. 사용법은 매우 간단하다.

위의 갤러리 레이아웃에서 별점을 위한 HStack도 존재하는데, 이들 역시 Lazy 하게 구성해야 할까?

정답은 “아니오”다. 이들은 화면에 보여졌을 때 모든 컨텐츠를 한 번에 볼 수 있다. 그렇기 때문에 LazyHStack을 사용해서 그 어떤 이득도 볼 수 없다. 만일 일반 Stack과 Lazy Stack 중 어떤 것을 사용해야 할지 고민된다면 일반 Stack을 사용하는 걸 권장한다.

Instruments를 사용해 프로파일링을 한 후 성능의 병목 현상을 발견했고 이를 해결할 때만 Lazy Stack을 사용하도록 하자

Grids

그리드 레이아웃을 위한 새로운 기본 레이아웃이 추가되었는데 LazyVGridLazyHGride가 그것이다. 이들의 사용법 역시 그리 어렵진 않다.

LazyVGrid 기준으로 원하는 행의 구성 정보와 함께 기존의 VStack 코드를 대체하였다. 그리고 이런 행의 정보를 나타내는 GridItem 역시 새로 추가되었다.

GridItem을 사용해 그리드 레이아웃의 각각의 아이템의 크기와 위치를 지정해 줄 수 있다.

이들은 기본적으로 유연하기(flexible) 때문에 위와 같이 세 개의 GridItem을 사용하면 각 행의 너비는 모두 동일한 너비를 갖게 된다.

GridItem은 단순히 갯수만이 아닌 최소 너비 값과 같은 특정 사이즈 크기를 이용해 원하는 그리드 레이아웃을 구성하는데 사용할 수 있다.

Lists

List 역시 기본 레이아웃 구성 요소 중 하나로 스크롤과 선택된 항목(selection) 관리와 같은 인터렉션을 지원하는 레이아웃 요소이다. List는 항상 컨텐츠를 Lazy 하게 불러온다.

이뿐만 아니라 이번에 추가된 기능으로 우린 리스트를 통해 컨텐츠를 그룹화하여 표현할 수 있게 되었다.

children keypath를 사용하는 생성자를 통해 우린 List의 컨텐츠를 쉽게 그룹화할 수 있게 되었다. 내부적으로 어떻게 이것이 가능한지 살펴보도록 하자.

Outlines

OutlineGroupForEach와 동일하게 데이터를 순회하지만 단일 계층의 flat 한 콜렉션 타입의 데이터를 순회하는 ForEach와 달리 OutlineGroup은 트리 구조 형태의 데이터 타입을 순회한다.

OutlineGroupSection과 함께 사용하면 .listStyle(_:)에 따라 다양한 기본 스타일의 헤더 뷰를 사용할 수 있다.

이렇게 계층화된 데이터를 사용해 동일한 외형의 Row를 사용하는 것이 아니라 서로 다른 데이터 타입이지만 단순히 이들을 계층화하고, 보여주기와 숨기기 기능을 사용하고 싶다면 이번에 새로 추가된 DisclosureGroup을 사용하면 된다.

OutlineGroup이 내부적으로 어떻게 동작하는지 살펴보자.

  1. 예제의 OutlineGroupgraphics 모델을 사용한다.
  2. OutlineGroup은 동일한 모델을 사용하는 ForEach로 확장된다.
  3. ForEachbodyDisclosureGroup으로 graphics의 아이템 하나를 사용한다.
  4. DisclosureGroup은 다시 하나의 graphic를 데이터로 갖는 OutlineGroupbody로 갖는다.

이런 1~4의 과정은 children이 없는 graphic을 찾을 때까지 반복된다. 이러한 계산 과정은 그룹이 확장되었을 때(사용자가 그룹을 확장시켰을 때)에만 진행되기 때문에 최소한의 과정만을 갖게 된다.

Comments