XLOG

[SwiftUI] Scroll Value 구하기 본문

Swift/SwiftUI

[SwiftUI] Scroll Value 구하기

X_PROFIT 2023. 1. 30. 23:36

사용할 방법은 GeometryReader 와 preference 를 이용한다.

그러기 위해 우리는 GeometryReader 를 먼저 알아야 한다.

GeometryReader는 컨테이너 뷰가 가지고 있는 사이즈, 좌표공간을 반환해주는 함수 이다.

그렇다면 preference 란 무엇일까?

주어진 preference(선호?)로 값을 set 해준다는게 무슨 말일까…..

이것은 SwiftUI 가 view의 사이즈, 위치를 어떻게 결정을 하는지에 대한 원리에 대한 이해가 필요하다.

자세히 작성을 하다보면 내용이 너무 길어진다. 그냥 간단하게 보통 상위뷰에서 하위뷰로 데이터를 전달하는데 가끔 우리는 하위뷰에서 상위뷰로 데이터를 전달을 하고 싶을 때가 생긴다. 그때 하위뷰가 원하는(선호하는) 데이터(사이즈, 위치 등)를 전달할때 사용을 하는 것이다.

그럼 의미를 알았으니 저 두가지를 사용하여 우리가 스크롤을 할때 스크롤된 데이터를 어떻게 구할까?

간단하게 순서를 정한다면

  1. preference에 사용할 key를 정의해준다.(preferencekey 프로토콜과 함께)
  2. GeometryReader를 이용하여 Scrollview 내부에서 스크롤에 따라 위치값을 받아올 수 있는 View 를 만든다.
  3. 그 View의 preference의 값을 변화시켜준다.
  4. onPreferenceChange를 이용하여 preference 값을 가져온다.
//preferencekey로 사용할 struct
struct ViewOffsetKey: PreferenceKey {
		typealias Value = CGFloat
		static var defaultValue = CGFloat.zero
		static func reduce(value: inout Value, nextValue: () -> Value) {
				value += nextValue()
		}
}

//some View 내부
ScrollView() {
		ForEach() {
		....
		}
}
// background가 아니라도 사용 가능
.background( Geometry {
		Color.clear.preference(key: ViewOffsetKey.self, value: -$0.frame(in: .named("scroll")).origin.y)
})
.onPreferenceChange(ViewOffsetKey.self) {
		// $0 이 스크롤 된 값
		print($0)
}

참고

https://stackoverflow.com/questions/62588015/get-the-current-scroll-position-of-a-swiftui-scrollview

https://protocorn93.github.io/tags/PreferenceKey/

https://velog.io/@kipsong/SwiftUI-Preference-Key-coordinatespace

https://ios-development.tistory.com/1166

https://swiftwithmajid.com/2020/01/15/the-magic-of-view-preferences-in-swiftui/