Grid
에 대해 알아보도록 합시다.
Lazy V(H)Grid
List와 Grid의 차이
Grid
는 List
와 친척이라고 생각하시면 됩니다. 일단 Grid
와 List
의 차이를 간단하게 그림으로 보겠습니다.
LazyV(H)Stack
과의 차이는 다음 게시물에서 다루겠습니다,
List
List
는 일반적으로 Vertical Direction
으로 목록을 나타내 준다고 보시면 됩니다. 가장 많이 사용되는 View
라고 생각하시면 됩니다.
Grid
Grid
는 horizontal Direction
으로 사진을 배열하여 화면을 구성하기 좋습니다.
가장 좋은 예로 Instargram
/ Pinterest
/ Netflix
의 레이아웃을 떠올리시면 됩니다.
Grid
Xcode에서 코드로 어떻게 사용하는지에 바로 알아보도록 하겠습니다.
우선 Grid가 어떤 식으로 되어있는지 확인해볼게요.
오..! LazyVGrid는 columns를 사용하여 반드시 GridItem이라는 매개변수를 같은 변수를 생성해줘야 하네요!
struct ContentView: View {
//목록을 1부터 1000까지 만듬
let data = Array(1...1000).map { "목록 \($0)"}
//화면을 그리드형식으로 꽉채워줌
let columns = [
GridItem(.adaptive(minimum: 100))
]
var body: some View {
}
}
GridItem(.adaptive(minimum: )
저는 레이아웃의 최소 사이즈를 100
으로 일단 정해서 화면을 그리드 형식으로 꽉 차게 만들었습니다. 이제 ScrollView
로 화면을 구성해주도록 하겠습니다.
LazyVGrid
이 단계에서 알아야 할 것은 LazyVGrid
입니다. LazyVGrid
를 작성해보면 자동으로 어떻게 사용해야 할지 아래 사진과 같이 나오게 됩니다.
var body: some View {
ScrollView {
LazyVGrid(columns: columns, spacing: 20) {
ForEach(data, id: \.self) {i in
Text(i)
}
}
.padding(.horizontal)
}
}
만약 목록 위에 사진이나 도형을 추가하려면 어떻게 해야 할까요? 바로, VStack
을 이용해야 합니다.
ScrollView {
LazyVGrid(columns: columns, spacing: 20) {
ForEach(data, id: \.self) {i in
//VStack으로 도형추가
VStack {
Capsule()
.fill(Color.yellow)
.frame(height: 50)
Text(i)
.foregroundColor(.secondary)
}
}
}
.padding(.horizontal)
}
이렇게 Grid
형식으로 뷰를 구성했습니다. 그럼 만약 '목록1
'부분을 한줄로 꽉 채우고 싶다면 어떻게 할까요?
위에서 'let columns = [ GridItem(.adaptive(minimum: 100))
' 우리는 최소 레이아웃 사이즈를 100
으로 설정했습니다. 이 부분을 수정해보도록 하겠습니다. .adaptive()
를 삭제하고 .flexibel()
확장자를 사용합니다.
flexible
의 최솟값과 최댓값을 할당해줘도 되지만, 만약 두 가지를 모두 쓰지 않으면 기본값으로 자동으로 화면을 꽉 채워줍니다.
이렇게 최솟값과 최댓값을 적어주지 않으면 사용자가 아이패드 또는 아이폰 미니 등을 사용해도 꽉 찬 화면을 볼 수 있겠죠?
let columns = [
GridItem(.flexible())
]
layout
쪽에 GridItem
을 추가해보면 어떤 뷰가 생성될까요?
let columns = [
//추가 하면 할수록 화면에 보여지는 개수가 변함
GridItem(.flexible()),
GridItem(.flexible()),
GridItem(.flexible()),
GridItem(.flexible())
]
화면의 여백이 너무 크다면 최댓값을 정해줘 보도록 하죠 :)
let columns = [
GridItem(.flexible(maximum: 80)),
GridItem(.flexible(maximum: 80))
]
예시
import SwiftUI
struct ContentView: View {
let columns: [GridItem] = [
GridItem(.fixed(50), spacing: nil, alignment: nil),
GridItem(.fixed(50), spacing: nil, alignment: nil),
GridItem(.fixed(50), spacing: nil, alignment: nil),
GridItem(.fixed(50), spacing: nil, alignment: nil),
GridItem(.fixed(50), spacing: nil, alignment: nil)
]
var body: some View {
LazyVGrid(columns: columns) {
ForEach(0..<50) { index in
Rectangle()
.frame(height: 50)
}
}
}
}
고급 예제
LazyGrid의 인스펙터를 확인해보면 아래와 코드를 확인할 수 있습니다.
이 인스펙터를 사용해보겠습니다. 우선 columns라는 변수를 하나 만들어주고 할당해주겠습니다.
let columns: [GridItem] = [
GridItem(.flexible(), spacing: nil, alignment: nil),
GridItem(.flexible(), spacing: nil, alignment: nil),
GridItem(.flexible(), spacing: nil, alignment: nil)
]
GridItem에 flexible수정자를 넣어 화면에 꽉 찰 수 있도록 해줬습니다.
import SwiftUI
struct ContentView: View {
let columns: [GridItem] = [
GridItem(.flexible(), spacing: nil, alignment: nil),
GridItem(.flexible(), spacing: nil, alignment: nil),
GridItem(.flexible(), spacing: nil, alignment: nil)
]
var body: some View {
ScrollView {
LazyVGrid(
columns: columns,
alignment: .center,
spacing: nil,
pinnedViews: [],
content: {
ForEach(0..<50) { index in
RoundedRectangle(cornerRadius: 10)
.fill(Color.blue)
.frame(height: 150)
}
})
}
}
}
Spacer()
body의 LazyVGrid spacing을 수정해가면서 간격 조절해보도록 하려고 합니다.
Section 추가
Section을 추가해서 한번 뷰를 구성해볼게요
ScrollView {
LazyVGrid(
columns: columns,
alignment: .center,
spacing: 6,
pinnedViews: [],
content: {
Section(header:
Text("첫 번째 섹션")
.font(.title)
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.background(Color.accentColor)
) {
ForEach(0..<10) { index in
RoundedRectangle(cornerRadius: 10)
.fill(Color.white)
.shadow(radius: 10)
.frame(height: 150)
.padding(5)
}
}
Section(header:
Text("두 번째 섹션")
.font(.title)
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.background(Color.accentColor)
) {
ForEach(0..<10) { index in
RoundedRectangle(cornerRadius: 10)
.fill(Color("Peach"))
.frame(height: 150)
.padding(5)
}
}
})
}
이제 아주 재미있는 기능을 하나 해보려고 합니다. pinnedViews를 우리는 [ ]로 아직 설정해주지 않았습니다. 이것을 다뤄보도록 할게요.
우선 pinnedViews[] 에 .을 입력해보면 아래와 같이 스니펫이 등장합니다.
위에서 우리는 Footer은 작성하지 않고 Header만 만들어줬기 때문에 header만 작동할 것 같죠? 바로 적용하고 결과 화면을 보도록 하죠!
전체 코드
<hide/>
import SwiftUI
struct ContentView: View {
let columns: [GridItem] = [
GridItem(.flexible(), spacing: 6, alignment: nil),
GridItem(.flexible(), spacing: 6, alignment: nil),
GridItem(.flexible(), spacing: 6, alignment: nil)
]
var body: some View {
ScrollView {
Rectangle()
.fill(Color.yellow)
.frame(height: 400)
LazyVGrid(
columns: columns,
alignment: .center,
spacing: 6,
pinnedViews: [.sectionHeaders],
content: {
Section(header:
Text("첫 번째 섹션")
.font(.title)
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.background(Color.accentColor)
) {
ForEach(0..<10) { index in
RoundedRectangle(cornerRadius: 10)
.fill(Color.white)
.shadow(radius: 10)
.frame(height: 150)
.padding(5)
}
}
Section(header:
Text("두 번째 섹션")
.font(.title)
.foregroundColor(.white)
.frame(maxWidth: .infinity)
.background(Color.yellow)
) {
ForEach(0..<50) { index in
RoundedRectangle(cornerRadius: 10)
.fill(Color("Peach"))
.frame(height: 150)
.padding(5)
}
}
})
}
}
}
마치 CSS의 sticky처럼 header가 고정되고 바뀌는 게 정말 재미있는 기능이네요 :)
기본적으로 LazyHGrid도 위와 동일하게 작동하기 때문에 LazyHGrid에 대해서는 간단하게 알아보도록 하겠습니다.🤟
LazyHGrid
위에서는 LazyVGrid
를 사용했다면 가로로 스크롤을 배치하고 싶을 땐 LazyHGrid
를 사용해야 합니다.
위에서 썼던 코드를 수정하여 사용하도록 하죠. 수정해야 할 부분은 ScrollView
와 LazyVGrid
쪽 입니다.LazyVGrid
에서 사용됐던 columns
이 rows
로 바뀐 것을 확인할 수 있습니다.
struct ContentView: View {
//목록을 1부터 1000까지 만듬
let data = Array(1...1000).map { "목록 \($0)"}
//화면을 그리드형식으로 꽉채워줌
let layout = [
GridItem(.flexible(maximum: 80)),
GridItem(.flexible(maximum: 80)),
GridItem(.flexible(maximum: 80)),
GridItem(.flexible(maximum: 80))
]
var body: some View {
//스크롤뷰를 horizontal로 수정
ScrollView(.horizontal) {
//LazyVGrid에서 LazyHGrid로 수정
LazyHGrid(rows:layout, spacing: 20) {
ForEach(data, id: \.self) {i in
VStack {
Capsule()
.fill(Color.yellow)
.frame(height: 30)
Text(i)
.foregroundColor(.secondary)
}
}
}
.padding(.horizontal)
}
동일한 결괏값 다른 코드
import SwiftUI
struct ContentView: View {
//화면을 그리드형식으로 꽉채워줌
let layout = [
GridItem(.flexible(maximum: 80)),
GridItem(.flexible(maximum: 80)),
GridItem(.flexible(maximum: 80)),
GridItem(.flexible(maximum: 80))
]
var body: some View {
ScrollView(.horizontal) {
LazyHGrid(rows:layout, spacing: 20) {
ForEach(0...1000, id: \.self) { i in
VStack {
Capsule()
.fill(Color.yellow)
.frame(height: 30)
Text("목록 \(i)")
.foregroundColor(.secondary)
}
}
}
.padding(.horizontal)
}
}
}
읽어주셔서 감사합니다🤟
본 게시글의 전체 코드 GitHub 👇🏻
'SWIFTUI > View layout' 카테고리의 다른 글
SwiftUI : Picker / Picker Style / Section (0) | 2021.05.13 |
---|---|
SwiftUI : Sheet / FullScreenCover (@Environment / presentationMode) (0) | 2021.05.11 |
SwiftUI : ScrollView (1) | 2021.05.08 |
SwiftUI : Form (Toggle / disabled / If ) (0) | 2021.03.19 |
SwiftUI : ZStack ( Spacer / offset / zIndex ) (0) | 2021.03.15 |