SwiftUI - ScrollView

이재원·2024년 7월 2일
0

SwiftUI

목록 보기
1/9
post-thumbnail

frame(maxWidth: .infinity)

해당 코드를 ScrollView 하위 뷰에 적용을 하면 화면 전체를 클릭하여 스크로 할 수 있다.

Horiznotal 방향으로 변경

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)
        }
    }
}

showsIndicators

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()
                            }
                        }
                    })
                }
            }
        }
    }
}

LazyVStack

아이템이 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()
                            }
                        }
                    })
                }
            }
        }
    }
}

출처
https://seons-dev.tistory.com/entry/ScrollView

profile
20학번 새내기^^(였음..)

0개의 댓글