Это моя настройка, чтобы выяснить направление прокрутки:
Код: Выделить всё
ScrollView {
content
.background(scrollDirectionTrackerView)
.onPreferenceChange(ScrollOffsetKey.self) { updatedOffset in
updateScrollDirection(updatedOffset)
}
}
.coordinateSpace(name: "scrollView")
private var scrollDirectionTrackerView: some View {
GeometryReader { proxy in
Color.clear.preference(key: ScrollOffsetKey.self,
value: -proxy.frame(in: .named(coordinateSpaceKey)).origin.y)
}
}
Код: Выделить всё
// Somewhere within the View
private let minimumDirectionChangeOffset = 16.0
private var scrollDirectionUpdateHandler: ((ScrollDirection) -> Void)?
@State private var currentDirection = ScrollDirection.none
@State private var previousScrollOffset = CGFloat.zero
private func updateScrollDirection(_ newOffset: CGFloat) {
let offsetDifference = previousScrollOffset - newOffset
var updatedDirection = currentDirection
if abs(offsetDifference) > minimumDirectionChangeOffset {
if offsetDifference > 0 {
updatedDirection = axis == .vertical ? .up : .backward
} else {
updatedDirection = axis == .vertical ? .down : .forward
}
previousScrollOffset = newOffset
}
// Only publish if we have a different direction
if updatedDirection != currentDirection {
currentDirection = updatedDirection
scrollDirectionUpdateHandler?(currentDirection) // The subscriber performs an animation
}
}
Если я выполняю быструю прокрутку в любом направлении, это работает хорошо.< /p>
Однако, когда я перетаскиваю очень медленно, я чувствую, что либо возникает состояние гонки с несколькими потоками, обращающимися к этой функции, либо что-то еще, но направление задается несколько раз, вызывая несколько анимаций, что приводит к работа пользователя нестабильна из-за анимации.
Мне интересно, есть ли более элегантный способ справиться с этим:
- с помощью какого-то устранения дребезга
- какой-то семафор/блокировка, позволяющая заблокировать функцию
- или даже лучше математику?
Анимация, которую необходимо выполнить, — это скрытие/отображение представления на основе UIKit, поэтому анимация, которая происходит, представляет собой блок UIView.animate с длительностью 0,5.< /p>
Я попробовал этот старый ответ, но он мне не помог.
Есть ли лучший способ предотвратить многократное изменение направления прокрутки при медленном перетаскивании ?
Наконец, мне нужна поддержка iOS 16+.
Подробнее здесь: https://stackoverflow.com/questions/793 ... in-swiftui
Мобильная версия