ScrollView
SwiftUI
의 ScrollView
를 사용하면 뷰의 Scroll
컨테이너를 비교적 쉽게 만들 수 있습니다. 그 이유는 내부에 배치 한 콘텐츠에 맞게 자동으로 크기가 조정되고 안전 영역을 피하기 위해 추가 삽입물을 자동으로 추가하기 때문입니다.
List
/ form
으로 Scroll
되는 데이터 테이블을 만드는 방법도 있지만, 임의 날짜를 Scroll
하려는 경우에는 ScrollView
로 전환해야 합니다. 예시로 1
부터 100
까지 나오는 ScrollView
를 만들어 봅시다.
ScrollView() {
VStack {
ForEach(1..<100) {
Text("Item \($0)") //$표시 필수
.font(.title)
}
} //VStack
}
frame(maxWidth: .infinity)
위 코드처럼 작성하면 1
부터 100
까지 나와있는 것을 확인할 수 있지만, 화면 중앙을 탭 해야 Scroll
이 작동됩니다.
이것은 효율성이 떨어지기 때문에 아래 코드를 추가해주면 해결이 가능합니다.
//ScrollView 내부에서 사용
.frame(maxWidth: .infinity)
ScrollView() {
VStack {
ForEach(1..<100) {
Text("Item \($0)") //$표시 필수
.font(.title)
}
} //VStack
//중앙에서만 탭(스크롤)이 가능했던것을 프레임으로 전체로 늘려줌
.frame(maxWidth: .infinity)
}
Horizontal 방향으로 변경
ScrollView
는 기본적으로 수직이지만, 첫 번째 매개 변수로 .horizontal
을 전달하여 축을 제어할 수 있습니다. 따라서 이전 예제를 다음과 같이 수평으로 뒤집을 수 있습니다.
ScrollView(.horizontal) {
HStack {
ForEach(0..<10) {
Text("숫자 \($0)")
.foregroundColor(.black)
.font(.largeTitle)
.background(Color.yellow)
}
}
.frame(maxHeight: .infinity)
}
struct ContentView: View {
var body: some View {
VStack {
Divider()
ScrollView(.horizontal) {
HStack {
ForEach(0..<100) { i in
CircleView(label: "\(i)")
.foregroundColor(.white)
}
}
.padding()
}
.frame(height: 100)
Divider()
Spacer()
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
struct CircleView: View {
@State var label: String
var body: some View {
ZStack {
Circle()
.fill(Color.blue)
.frame(width: 70, height: 70)
Text(label)
}
}
}
스크롤 바 숨기기
ScrollView
코드를 작성 후 괄호()
를 열어보면 아래와 같이 스니팻 목록이 나오게 됩니다.
이 코드를 사용하여 스크롤바를 숨기거나 타나 나게 할 수 있고, 또 위에서 배웠던 방향을 쉽게 정해줄 수 있습니다.
우선 기본적인 ScrollView
코드와 indicators을 사용한 코드를 비교해 볼게요.
ScrollView {
VStack {
ForEach(0..<50) { index in
Circle()
.fill(Color.red)
.frame(height: 100)
}
}
}
ScrollView(.vertical, showsIndicators: false, content: {
VStack {
ForEach(0..<50) { index in
Circle()
.fill(Color.red)
.frame(height: 100)
}
}
})
이제 방향을 정해줄 수 있는데 vertical으로 정해주면 VStack
을 자식 뷰로 채택해야 하고, horizontal이면 HStack
을 채택해야 합니다.
Vertical
ScrollView(.vertical, showsIndicators: false, content: {
VStack {
ForEach(0..<50) { index in
Circle()
.fill(Color.red)
.frame(height: 100)
.overlay(Text("vertical").foregroundColor(.white))
}
}
})
Horizontal
ScrollView(.horizontal, showsIndicators: false, content: {
HStack {
ForEach(0..<50) { index in
Circle()
.fill(Color.red)
.frame(width: 100)
.overlay(Text("horizontal").foregroundColor(.white))
}
}
})
ScrollView 안에 ScrollView
기본적으로 ScrollView
는 Vertical로 되어 있습니다. 그런데 기본적으로 세로 방향은 유지하되, 각 행에는 Horizontal
형식의 아이템이 오게 할 수도 있습니다. 바로 ScrollView
안에 자식 뷰로 ScrollView
를 넣어주는 것이죠. 코드로 살펴보겠습니다.
ScrollView {
VStack {
ForEach(0..<20) { index in
ScrollView(.horizontal, showsIndicators: false, content: {
HStack {
RoundedRectangle(cornerRadius: 20)
.fill(Color.white)
.frame(width: 200, height: 150)
.shadow(radius: 10)
.padding()
}
})
}
}
}
이렇게 코드를 작성하고 프리뷰를 실행해볼게요.
그럼 위 아이템에 horizontal아이템을 어떻게 넣을까요? 바로 ForEach
문을 다시 한번 넣어줘야 합니다.
ScrollView {
VStack {
ForEach(0..<20) { index in
ScrollView(.horizontal, showsIndicators: false, content: {
HStack {
ForEach(0..<10) { _ in
RoundedRectangle(cornerRadius: 20)
.fill(Color.white)
.frame(width: 200, height: 150)
.shadow(radius: 10)
.padding()
}
}
})
}
}
}
LazyV(H)Stack
위에서 ForEach
로 아이템을 20개가 생기도록 만들어줬습니다.
하지만 이 아이템이 100개 혹은 300개 이상이라고 할 때 한 가지 문제가 있습니다. 만약 사용자가 앱을 클릭해서 로드를 한다면 한 번에 100개의 아이템이 로드되고 만약 이미지가 많거나 고화질일수록 로드하는데 시간이 많이 걸리죠.
이럴 때 사용해야 하는 것이 LazyStack
입니다.
Lazy
는 스크롤을 할 때 그 화면에 보이는 아이템이 동시에 다운로드됩니다. 그렇기 때문에 광대한 데이터 사용을 막아 줄 수 있죠.
사용법은 아주 간단합니다.
그저 VStack
과 HStack
을 LazyVStack
/ LazyHStack
으로 수정해주기만 하면 됩니다.
ScrollView {
LazyVStack {
ForEach(0..<20) { index in
ScrollView(.horizontal, showsIndicators: false, content: {
LazyHStack {
ForEach(0..<10) { _ in
RoundedRectangle(cornerRadius: 20)
.fill(Color.white)
.frame(width: 200, height: 150)
.shadow(radius: 10)
.padding()
}
}
})
}
}
}
읽어주셔서 감사합니다🤟
'SWIFTUI > View layout' 카테고리의 다른 글
SwiftUI : Sheet / FullScreenCover (@Environment / presentationMode) (0) | 2021.05.11 |
---|---|
SwiftUI : Lazy V(H)Grid (4) | 2021.05.08 |
SwiftUI : Form (Toggle / disabled / If ) (0) | 2021.03.19 |
SwiftUI : ZStack ( Spacer / offset / zIndex ) (0) | 2021.03.15 |
SwiftUI : FixedSize - View의 크기를 동일한 너비/높이로 (1) | 2021.03.14 |