티스토리 뷰
오늘은 ScrollViewReader에 대해 알아보자
먼저 ScrollView와 ScrollViewReader는 무엇이 다른걸까??
ScrollView
스크롤 뷰는 단순히 스크롤 할 수 있는 뷰를 의미한다!
그래서 스크롤이 가능한 뷰에 사용하고 싶을 때 사용하면 된다.
ScrollViewReader
반면 ScrollViewReader는 현재 스크롤링을 감지하여 자동으로 스크롤되어 필요한 포인트로 위치 변경해주는 기능이 있다
하위 View, ScrollView를 스크롤하기 위해 Proxy라는것과 함께 작업할 수 있도록 프로그래밍 방식의 스크롤을 제공하는 뷰이다.
ScrollViewReader를 사용하려면 내부 뷰가 ScrollView로 감싸져있어야 한다.
-> ScrollViewReader를 사용한다고 ScrollView를 사용하지 않거나 단독으로 사용하면 안됨!!!!
ScrollViewReader를 적용한 예시
오늘 날짜가 27일이면, 캘린더에서 22일을 눌렀을 때 22일로 지출내역로 이동하는 것을
시뮬레이터에서 확인할 수 있다
사용방법
ScrollViewReader { proxy in
ScrollView {
VStack {
if groupedSpendings().isEmpty {
NoSpendingHistoryView()
} else {
LazyVStack(spacing: 0 * DynamicSizeFactor.factor()) {
ForEach(groupedSpendings(), id: \.key) { date, spendings in
Spacer().frame(height: 10 * DynamicSizeFactor.factor())
Section(header: headerView(for: date)) {
Spacer().frame(height: 12 * DynamicSizeFactor.factor())
ForEach(spendings, id: \.id) { item in
let iconName = SpendingListViewCategoryIconList(rawValue: item.category.icon)?.iconName ?? ""
ExpenseRow(categoryIcon: iconName, category: item.category.name, amount: item.amount, memo: item.memo)
Spacer().frame(height: 12 * DynamicSizeFactor.factor())
}
.onAppear {
Log.debug("spendings: \(spendings)")
Log.debug("group: \(groupedSpendings())")
}
}
.id(date) // ScrollViewReader를 위한 ID 추가
}
Spacer().frame(height: 18 * DynamicSizeFactor.factor())
}
}
}
if !groupedSpendings().isEmpty {
Button(action: {
changeMonth(by: -1)
}, label: {
ZStack {
Rectangle()
.frame(width: 103 * DynamicSizeFactor.factor(), height: 40 * DynamicSizeFactor.factor())
.foregroundColor(Color("Gray01"))
.cornerRadius(26)
Text(monthTitle(from: spendingHistoryViewModel.currentDate))
.font(.B1SemiboldeFont())
.foregroundColor(Color("Gray04"))
.padding(.horizontal, 20)
.padding(.vertical, 12)
}
})
.padding(.bottom, 48)
.onChange(of: selectedDateToScroll) { date in
if let date = date {
withAnimation {
proxy.scrollTo(date, anchor: .top)
}
}
}
.onAppear {
proxy.scrollTo(selectedDateToScroll, anchor: .top)
}
}
}
}
ScrollViewReader가 필요한 뷰 최상단에 ScrollViewReader를 사용하고 하위에 ScrollView를 사용하여 뷰를 감싸준다.
그리고 ScrollViewReader가 감지가 필요한 부분에 id()를 넣어주면
scrollTo메서드에 의해서 필요한 id로 자동으로 스크롤링이 되는 구조이다.
적용된 예시에서를 살펴보자
1️⃣ onChange를 통해 selectedDateToScroll이라는 변수의 값이 변경될 때 마다 proxy.scrollTo(date, anchor: .top)을 실행시켰다.
2️⃣ onAppear를 통해 proxy.scrollTo(selectedDateToScroll, anchor: .top) 을 통하여 사용자가 선택했던 날짜를 기준으로 뷰가 로드되어 해당 날짜로 스크롤을 감지하도록 뷰를 새로고침하게 한다!
anchor은 .top, .bottom, .center이 있고 어떤 방향으로 스크롤 될 지를 결정해주기 때문에 원하는 방식에 맞춰서 사용하면 될 듯하다~
'iOS > SwiftUI' 카테고리의 다른 글
[iOS/SwiftUI] .background()에 NavigationLink를 중첩시키기 (0) | 2024.08.03 |
---|---|
[iOS/SwiftUI] Custom Week Calendar 구현하기 (0) | 2024.07.27 |
[iOS/SwiftUI] @EnvironmentObject로 전역 상태 관리하기 (0) | 2024.05.18 |
[iOS/SwiftUI] SecureField 사용시 Strong Password (0) | 2024.04.22 |
[iOS/SwiftUI] SwiftUI 에서 LifeCycle 관리 (0) | 2024.04.05 |
- Total
- Today
- Yesterday
- ScrollViewReader
- 스위프트
- XCTest
- 코딩테스트
- 가장가까운같은글자
- ObservableObject
- imagepicker
- swiftUI
- MainActor
- combine
- closure
- CoreData
- pbxproj
- CustomCalendar
- securefield
- 클로저
- rxswift
- LazyVGrid
- 병합충돌
- 백준
- mergeconflict
- 둘만의 암호
- mlmodel
- 16173
- SWIFT
- ios
- Fastlane
- Xcode
- 프로그래머스
- UIKit
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |