- actualContentHeight 通过 GeometryReader 获取真实内容高度 - scrollProgress 使用实际高度计算,精度显著提升 - #36 ReadingEventCollector 已清理完毕(无 ObservableObject/Combine) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
5af29af549
commit
d9828bc3c8
@ -100,6 +100,7 @@ struct MaterialReaderView: View {
|
|||||||
@State private var scrollProgress: CGFloat = 0
|
@State private var scrollProgress: CGFloat = 0
|
||||||
@State private var hasRestoredPosition = false
|
@State private var hasRestoredPosition = false
|
||||||
@State private var restoreBlockId: String?
|
@State private var restoreBlockId: String?
|
||||||
|
@State private var actualContentHeight: CGFloat = 1
|
||||||
|
|
||||||
private let title: String
|
private let title: String
|
||||||
private let knowledgeBaseId: String?
|
private let knowledgeBaseId: String?
|
||||||
@ -233,15 +234,17 @@ struct MaterialReaderView: View {
|
|||||||
}
|
}
|
||||||
.padding(.horizontal, 20).padding(.top, 8).padding(.bottom, 100)
|
.padding(.horizontal, 20).padding(.top, 8).padding(.bottom, 100)
|
||||||
.background(GeometryReader { geo in
|
.background(GeometryReader { geo in
|
||||||
Color.clear.preference(
|
Color.clear
|
||||||
key: ScrollOffsetKey.self,
|
.preference(key: ScrollOffsetKey.self, value: geo.frame(in: .named("scroll")).minY)
|
||||||
value: geo.frame(in: .named("scroll")).minY
|
.onAppear { actualContentHeight = geo.size.height }
|
||||||
)
|
|
||||||
})
|
})
|
||||||
|
.onChange(of: vm.blocks.count) { _,_ in
|
||||||
|
// Height will be updated by GeometryReader on next render
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.coordinateSpace(name: "scroll")
|
.coordinateSpace(name: "scroll")
|
||||||
.onPreferenceChange(ScrollOffsetKey.self) { offset in
|
.onPreferenceChange(ScrollOffsetKey.self) { offset in
|
||||||
scrollProgress = min(1, max(0, -offset / max(contentHeightEstimate, 1)))
|
scrollProgress = min(1, max(0, -offset / max(actualContentHeight, 1)))
|
||||||
reportScrollPosition()
|
reportScrollPosition()
|
||||||
}
|
}
|
||||||
.onChange(of: restoreBlockId) { _, target in
|
.onChange(of: restoreBlockId) { _, target in
|
||||||
@ -256,12 +259,6 @@ struct MaterialReaderView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Estimate total block area height for scroll progress calculation
|
|
||||||
private var contentHeightEstimate: CGFloat {
|
|
||||||
let count = max(vm.blocks.count, 1)
|
|
||||||
return CGFloat(count) * 80
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Build a NoteAnchor from the current scroll position (for quick note).
|
/// Build a NoteAnchor from the current scroll position (for quick note).
|
||||||
private func buildAnchor() -> NoteAnchor? {
|
private func buildAnchor() -> NoteAnchor? {
|
||||||
guard let pos = collector.lastPosition else { return nil }
|
guard let pos = collector.lastPosition else { return nil }
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user