[SwiftUI] Scroll View

silverCastle·2022년 3월 12일

Storyboard에서 Scroll View를 생성했을 당시에 복잡하고 쉽지 않았던 거에 비해 SwiftUI로 Scroll View를 생성하니까 정말 신세계였다.
Scroll View는 기존에 있는 앱에서도 자주 보일 만큼 많이 쓰인다고 할 수 있으므로 제대로 배워보자.

먼저 Scroll View를 하나 생성해준다.

        ScrollView {
            Text("Hello, world!")
                .padding()
        }

하지만 보시다시피, 화면 가운데에서만 스크롤이 작동되는 것을 알 수 있다.
이를 해결하기 위해 아래의 코드를 추가해주고 좀 더 많은 콘텐츠를 삽입해준다.

        ScrollView {
            VStack {
                ForEach(1..<100) {_ in
                    Text("Hello, world!")
                        .padding()
                }
            }
            .frame(maxWidth: .infinity) // 화면 가운데뿐만 아니라 전체에서 스크롤 가능하게 해줌
        }

기본적으로 수직으로 Scroll이 생기는데 수평으로 생성할 수도 있다.

        ScrollView(.horizontal) {
            HStack {
                ForEach(1..<100) {_ in
                    Text("Hello, world!")
                        .padding()
                }
            }
            .frame(maxHeight: .infinity) // 화면 가운데뿐만 아니라 전체에서 스크롤 가능하게 해줌
        }

화면 오른쪽 혹은 아래를 보면 Scroll Bar가 생기는 걸 알 수 있는데 이를 사용자의 기호에 맞게 없앨 수 있다. 아래의 코드는 현재 수평으로 생성하였는데 수직으로 Scroll View를 생성하였다면
.horizontal ➡️ .vertical
HStack ➡️ VStack
maxHeight ➡️ maxWidth
로 바꿔주면 된다.

        ScrollView(.horizontal, showsIndicators: false) {
            HStack {
                ForEach(1..<100) {_ in
                    Text("Hello, world!")
                        .padding()
                }
            }
            .frame(maxHeight: .infinity) // 화면 가운데뿐만 아니라 전체에서 스크롤 가능하게 해줌
        }

마지막으로, Scroll View 안에 Scroll View를 넣을 수 있는데 Scroll View 안에 많은 콘텐츠가 존재한다면 한번에 많은 콘텐츠를 받아오기 때문에 시간이 오래 걸리므로 Lazy Stack을 사용한다.
Lazy Stack은 Scroll을 할 때 화면에 보이는 콘텐츠를 받아오기 때문에 데이터와 시간을 절약할 수 있다.
아래는 수직 Scroll에 각 행이 수평 Scroll인 경우이다.

        ScrollView {
            LazyVStack {
                ForEach(1..<50) { _ in
                    ScrollView(.horizontal, showsIndicators: false) {
                        LazyHStack {
                            ForEach(0..<10)  { _ in
                                Circle()
                                    .fill(Color.blue)
                                    .frame(width: 100, height: 100)
                                    .padding()
                            }
                        }
                    }
                }
            }
        }

0개의 댓글