Код: Выделить всё
LazyVStack
На очень базовом уровне мой список:
Код: Выделить всё
ScrollView {
LazyVStack {
ForEach(feed.sections) { section in
SectionView(section: section).id(section.id)
}
}
.scrollTargetLayout()
}
.scrollPosition($position, anchor: .top)
Загрузка больше элементов при прокрутке вниз не является проблемой . Позиция прокрутки не должна меняться, и мы можем свободно делать это столько, сколько нам нравится, не ломая взаимодействие каким -либо образом. Я просто не могу заставить его работать хорошо. Общий совет - использовать модификатор прокрутки. В соответствии с документами: < /p>
для положений идентификации просмотра, Swiftui попытается сохранить представление с помощью идентификации, указанной в предоставленном привязке, видимых, когда возникают события, которые могут вызвать его прокрутку системы. Некоторые примеры их включают в себя: данные, поддерживающие содержание представления прокрутки, повторно упорядочено. Размер вида прокрутки меняется, например, когда окно изменяется на macOS или во время вращения на iOS. Первоначально представление прокрутки излагает его содержимое, которое не выполняет наибольшее представление, но привязка имеет идентичность другого представления. Как только изменчивость высоты вводится, поведение восстановления прокрутки становится очень непредсказуемым при совокупности элементов. Любая попытка восстановления прокрутки, как правило, сталкивается с проблемами, связанными с точностью, сохранением скорости прокрутки или временем с условиями гонки. Даже здесь это вряд ли идеально - след памяти растет логарифмично с длиной списка, а восстановление прокрутки вызывает вспышки контента по мере его приготовления иногда. Вы можете увидеть мое дрянное создание здесь: < /p>
struct FeedView: View {
var feed: FeedModel
@State private var position = ScrollPosition()
@State var edgeLock: Bool = true
@State var restorationQueued: Bool = false
@MainActor
func restore(y: CGFloat) {
var tx = Transaction()
tx.scrollPositionUpdatePreservesVelocity = true
tx.isContinuous = true
withTransaction(tx) {
position = ScrollPosition(y: y)
}
restorationQueued = false
Task {
edgeLock = false
}
}
var body: some View {
ScrollView {
VStack {
ForEach(feed.sections) { section in
SectionView(section: section).id(section.id)
}
}
.onGeometryChange(for: CGFloat.self) { $0.size.height } action: { prev, next in
if (restorationQueued) {
let delta = next - prev // This is not perfect, need to add contentInsets too I think
restore(y: delta)
}
}
.scrollTargetLayout()
}
.scrollPosition($position, anchor: .top)
.onAppear() {
position = ScrollPosition(id: feed.rootID)
Task {
edgeLock = false
}
}
.onScrollGeometryChange(for: ScrollGeometry.self) { $0 } action: { prev, next in
let y = next.contentOffset.y
let topEdge = -next.contentInsets.top
let bottomEdge = next.contentSize.height - next.containerSize.height + next.contentInsets.bottom
let nearTop = y = bottomEdge - 20
guard !edgeLock, nearTop else { return }
if (nearTop) {
edgeLock = true
restorationQueued = true
feed.extendUp()
}
}
}
}
< /code>
Все, что сказано - есть ли здесь решение? Scrollview имеет некоторую очень удобную эвристику (а именно ее способность прокручивать конкретный элемент, взаимодействие с LazyVstack, Scroll Transitions и т. Д.), И я не могу себе представить, что необходимо переопределить тех, кто на более низком уровне appkit или uikit. Приносим извинения за что -нибудь смешное.
Пожалуйста, дайте мне знать, если есть какие -либо хорошие решения для этого!
Подробнее здесь: https://stackoverflow.com/questions/797 ... t-is-it-po