fix: #34 #35 移除 contentHeightEstimate 80px 硬编码

- actualContentHeight 通过 GeometryReader 获取真实内容高度
- scrollProgress 使用实际高度计算,精度显著提升
- #36 ReadingEventCollector 已清理完毕(无 ObservableObject/Combine)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
wangdl 2026-06-06 19:22:08 +08:00
parent 5af29af549
commit d9828bc3c8

View File

@ -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 }