segregate files
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
import SwiftUI
|
||||
#if canImport(UIKit)
|
||||
import UIKit
|
||||
#endif
|
||||
|
||||
#if os(iOS)
|
||||
@MainActor
|
||||
struct ScrollOffsetObserver: UIViewRepresentable {
|
||||
let onOffsetChange: (CGFloat) -> Void
|
||||
|
||||
func makeUIView(context: Context) -> ScrollOffsetProbeView {
|
||||
let view = ScrollOffsetProbeView()
|
||||
view.onOffsetChange = onOffsetChange
|
||||
return view
|
||||
}
|
||||
|
||||
func updateUIView(_ uiView: ScrollOffsetProbeView, context: Context) {
|
||||
uiView.onOffsetChange = onOffsetChange
|
||||
uiView.attachIfNeeded()
|
||||
}
|
||||
}
|
||||
|
||||
@MainActor
|
||||
final class ScrollOffsetProbeView: UIView {
|
||||
var onOffsetChange: (CGFloat) -> Void = { _ in }
|
||||
|
||||
private weak var observedScrollView: UIScrollView?
|
||||
private var observation: NSKeyValueObservation?
|
||||
|
||||
override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
backgroundColor = .clear
|
||||
isUserInteractionEnabled = false
|
||||
}
|
||||
|
||||
required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
}
|
||||
|
||||
deinit {
|
||||
observation?.invalidate()
|
||||
}
|
||||
|
||||
override func didMoveToSuperview() {
|
||||
super.didMoveToSuperview()
|
||||
attachIfNeeded()
|
||||
}
|
||||
|
||||
override func didMoveToWindow() {
|
||||
super.didMoveToWindow()
|
||||
attachIfNeeded()
|
||||
}
|
||||
|
||||
func attachIfNeeded() {
|
||||
guard let scrollView = findEnclosingScrollView() else { return }
|
||||
guard scrollView !== observedScrollView else { return }
|
||||
|
||||
observation?.invalidate()
|
||||
observedScrollView = scrollView
|
||||
observation = scrollView.observe(\.contentOffset, options: [.initial, .new]) { [weak self] sv, _ in
|
||||
self?.onOffsetChange(sv.contentOffset.y)
|
||||
}
|
||||
}
|
||||
|
||||
private func findEnclosingScrollView() -> UIScrollView? {
|
||||
var view: UIView? = self
|
||||
while let current = view {
|
||||
if let scrollView = current as? UIScrollView {
|
||||
return scrollView
|
||||
}
|
||||
view = current.superview
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user