안녕하세요.
늦은 감이 있지만 WWDC20 'Stacks, Grids, and Outlines in SwiftUI' 공부해 보고 내용 정리할게요.
# 개요
SwiftUI의 layout primitives에 대해 알아보자!
# Stacks
ScrollView와 VStack을 활용하면 왼쪽과 같은 화면을 만들 수 있어요.
이때 한 가지 문제점이 있어요.
VStack 요소가 늘어날수록(=이미지가 하나씩 추가될수록) 화면에 View를 그릴 때 시간이 오래 걸리게 됩니다.
모든 요소를 loading 하는데 시간이 오래 걸리는 것이죠.
이럴 때 LazyVStack, LazyHStack을 사용하면 됩니다.
LazyVStack 또는 LazyHStack은 VStack, HStack과 동일하지만 컨텐츠가 화면에 표시될 때 점진적으로 렌더링 됩니다.
Lazy 뷰는 이미지를 load 하는 동안 메인 스레드를 bloack 하지 않으며 앱의 메모리 공간이 불필요하게 커지는 것을 방지합니다.
코드상으론 단순하게 VStack -> LazyStack으로 바꿔주면 됩니다.
ScrollView와 Stack을 사용해서 많은 이미지를 화면에 출력하는 간단한 예시를 만들어봤는데요.
일반 Stack을 사용하면 한 번에 모든 요소를 loading 하기 때문에 CPU 사용량과 메모리 사용량이 매우 높게 나오는 반면
CPU | Memory |
![]() |
![]() |
Lazy Stack을 사용하면 점진적으로 loading하기 때문에 CPU 사용량이 적으며 메모리 사용량도 스크롤할 때에만 증가합니다.
CPU | Memory |
![]() |
![]() |
# Grids
그냥 VStack, HStack을 사용하면 iPad처럼 화면이 넓은 환경에선 아래처럼 널찍하게 나와요.
LazyVGrid, LazyHGrid를 사용하면 격자 형태로 뷰를 구성할 수 있어요.
아래는 Lazy Grid 뷰를 활용한 예시입니다.
Lazy Grid 뷰는 윈도우 창 크기를 임의로 조정할 수 있는 macOS에서 매우 유용합니다.
# Lists, OutlineGroup, DisclosureGroup
List 뷰는 항상 lazy 하게 contents를 load 합니다.
또한, List 생성자에 keypath를 인자로 받는 children이란 매개변수를 활용하면 트리 구조의 계층적 List 뷰를 만들 수 있어요.
좀 더 커스텀해서 사용하고 싶을 때 OutlineGroup을 사용합니다.
[참고] List에서 필요한 데이터는 Collection이지만 OutlineGroup에서 필요한 데이터는 Collection이 아닌 점 참고하세요!
단, OutlineGroup에서 필요한 데이터는 Identified data 이어야 합니다.
더 깊게 들어가볼게요.
어쩔 땐 계층 구조는 유지하되 숨기고 싶은 경우(폴딩)가 있을 수 있어요.
숨김 여부를 컨트롤하고 싶을 땐 DisclosureGroup을 사용합니다.
(isExpanded 파라미터로 접을지 말지 여부를 설정할 수 있어요.)
## OutlineGroup과 DisclosureGroup 내부 동작
OutlineGroup으로 계층 뷰를 그리려고 할 때
내부에선 ForEach를 사용합니다.
그리고 ForEach의 body는 DisclosureGroup이 되는 거예요.
DisclosureGroup의 Label에는 현재 계층의 요소를 넣어주고
DisclsoureGroup의 content(=하위 계층)는 또다시 OutlineGroup이 됩니다.
그리고 이 방식은 자식이 없을 때까지 재귀적으로 계속됩니다.
# Form
설정 목록을 그릴 땐 Form을 사용하세요.
# 참고
Stacks, Grids, and Outlines in SwiftUI - WWDC20 - Videos - Apple Developer
Display detailed data in your SwiftUI apps more quickly and efficiently with improved stacks and new list and outline views. Now...
developer.apple.com
이번 글은 여기서 마무리.
'WWDC' 카테고리의 다른 글
[WWDC20] State, Binding, StateObject, ObservedObject (0) | 2024.02.19 |
---|---|
[WWDC20] App essentials in SwiftUI (0) | 2024.01.15 |
[WWDC23] Get started with privacy manifests (30) | 2023.08.20 |
[WWDC23] Verify app dependencies with digital signatures (0) | 2023.08.16 |
[WWDC22] Explore App Tracking Transparency (0) | 2023.08.05 |