해당 코드를 ScrollView 하위 뷰에 적용을 하면 화면 전체를 클릭하여 스크로 할 수 있다.
ScrollView는 기본적으로 수직이지만, 첫 번째 매개변수로 .horizontal
을 전달하여 수평 축으로 바꿀 수 있다.
struct HorizontalScrollView: View {
var body: some View {
ScrollView(.horizontal) {
HStack {
ForEach(0..<10) {
Text("숫자 \($0)")
.foregroundColor(.black)
.font(.largeTitle)
.background(Color.yellow)
}
}
.frame(maxHeight: .infinity)
}
}
}
ScrollView의 showsIndicators를 설정해 주면 스크롤 바가 화면의 나타나는 유무를 정할 수 있다.
struct VerticalAndHorizontalScrollView: View {
var body: some View {
// 스크롤 바가 나타나지 않음
// 스크롤 방향은 vertical과 horizontal을 선택하면 되는데,
// vertical 선택시 자식 뷰로 VStack을 선택해 줘야 하고
// horiznotal 선택시 자식 뷰로 HStack을 선택해 줘야 함
ScrollView(.vertical, showsIndicators: false, content: {
VStack {
ForEach(0..<50) { index in
Circle()
.fill(Color.red)
.frame(height: 100)
.overlay(Text("vertical").foregroundColor(.white))
}
}
})
Divider()
ScrollView(.horizontal, showsIndicators: false, content: {
HStack {
ForEach(0..<50) { index in
Circle()
.fill(Color.red)
.frame(width: 100)
.overlay(Text("horizontal").foregroundColor(.white))
}
}
})
}
}
다음 코드는 Circle() 뷰를 추가하여 ScrollView를 나타낸 예제이다.
struct CircleScrollView: 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 CircleView: View {
@State var label: String
var body: some View {
ZStack {
Circle()
.fill(Color.blue)
.frame(width: 70, height: 70)
Text(label)
}
}
}
스크롤 뷰 안에 스크롤 뷰를 넣으면 기본적으로는 수직으로 스크롤 하되 각 행은 수평으로 스크롤 할 수 있다.
struct ScrollViewInScrollView: View {
var body: some View {
// 기본적으로 ScrollView는 vertical로 구성되어 있음
// ScrollView안에 ScrollView를 넣어주어 기본적으로는 수직으로 스크롤 하되
// 각 행은 horizontal로 스크롤하게 할 수 있음
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()
}
}
})
}
}
}
}
}
아이템이 20~30개와 같이 적은 경우에는 ForEach 구문으로 뷰를 그려도 되지만, 100개 이상의 많은 아이템을 그려낼 경우에는 시간이 오래 걸릴 수 있다.(고화질의 이미지일 수록 더)
이런 경우에는 LazyVStack을 이용하면 되는데, Lazy는 스크롤 할 때 그 화면에 보이는 아이템이 동시에 다운로드 되도록 하여 광대한 데이터 사용을 막아 줄 수 있다.
struct LazyVStackScrollView: View {
var body: some View {
// 아이템이 20~30개와 같이 적은 수인 경우에는 ForEach로 작성해도 괜찮지만
// 만약 100개 이상의 많은 아이템을 로드해야 할 경우 시간이 오래 걸릴 수 있음
// 이럴 때 사용하는 것이 LazyVStack임
// Lazy는 스크롤 할 때 그 화면에 보이는 아이템이 동시에 다운로드 됨.
// 이런 이유로 광대한 데이터 사용 막아 줄 수 있음
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()
}
}
})
}
}
}
}
}