Starbucks Caramel Frappuccino
본문 바로가기
  • 그래 그렇게 조금씩
SwiftUI/SwiftUI(Intermediate)

12. ScrollViewReader 스크롤뷰 리더

by Toughie 2023. 5. 25.

⭐️ScrollViewReader 스크롤뷰 리더⭐️

채팅 앱들을 보면 가장 위로, 가장 아래로 스르륵 자동으로 스크롤 되는 기능이 있는 경우가 많다.

이런 기능은 ScrollViewReader를 통해서 구현할 수 있다.

 

스크롤뷰리더는 코드를 통해 스크롤을 할 수 있게 하는 뷰이다.

스크롤뷰프록시는 스크롤 가능한 뷰에서 코드를 통해 스크롤을 할 때 필요한 간접/대리값 정도로 이해할 수 있다.

 

수동으로 스크롤 하는 것이 아니라, 원하는 위치로 자동으로 스크롤 해서 이동하는 것을 구현해 보자.

 

//  Created by Toughie on 2023/05/25.
//

import SwiftUI

struct ScrollViewReaderPrac: View {
    @State var textFieldText: String = ""
    //이동 할 위치(id)
    @State var scrollToIndex: Int?
    
    var body: some View {
        VStack {
            TextField("Enter number ", text: $textFieldText)
                .padding(.leading)
                .frame(height: 55)
                .border(Color.gray)
                .padding(.horizontal)
                //넘버패드
                .keyboardType(.numberPad)
            
            Button("Warp") {
                withAnimation(.spring()) {
                    guard let index = Int(textFieldText) else { return }
                    scrollToIndex = index
                }
            }
            
            ScrollView {
                ScrollViewReader { proxy in

                    ForEach(0..<50) { index in
                        Text("Item Number \(index)")
                            .font(.headline)
                            .frame(height: 100)
                            .frame(maxWidth: .infinity)
                            .background(Color.white)
                            .cornerRadius(10)
                            .shadow(radius: 10)
                            .padding()
                            //루프의 인덱스를 id로 등록해준다.
                            .id(index)
                    }
                    //스크롤뷰리더 내부, ForEach에 .onChange 모디파이어
                    .onChange(of: scrollToIndex) { newValue in
                        withAnimation(.spring()) {
                        //proxy.scrollTo 메서드를 통해 특정 id로 자동 스크롤
                        //anchor는 해당 아이템이 뷰에서 어디에 위치할 것인가 정할 수 있음
						//(top, center, bottom)
                            proxy.scrollTo(newValue, anchor: .top)
                        }
                    }
                }
            }
        }
    }
}