Commit Graph
14 Commits
Author SHA1 Message Date
shenlei e59bad9abf PDF 阅读器新增点读热区、试读墙与阅读进度/书签持久化
宿主的点读书场景需要在 PDF 页面上叠加可点击热区(音频/视频/网页等),并支持
试读限制与阅读进度、书签的本地保存,这些能力此前 RDPDFReaderView 均不提供,
只能由宿主在阅读器之外自行叠加视图,无法跟随 SDK 的缩放、翻页和主题渲染同步。

新增 RDPDFReaderPageInteraction 描述热区(位置、图标、边框/填充样式、点击态、
闪烁与播放边框规则、内嵌视频),由新增的 RDPDFInteractionHotspotView 负责绘制,
SVG 图标经 RDPDFReaderSVGIconLoader(基于 SDWebImage/SDWebImageSVGCoder)异步
解码后回填,避免阻塞主线程;点击事件通过 interactionHandler 回传给宿主,媒体
播放、路由等业务仍留在宿主侧。底部工具栏新增点读提示与连播按钮,状态由宿主驱动。

试读墙对齐 EPUB 侧 RDEPUBReaderTrialPolicy 的设计:以页为限制单位,可读页数在
配置了 trialPolicy 且宿主经 delegate 提供墙视图时生效,原始总页数、缩略图、目录
换算不受影响,只有传给 RDPDFReaderView 的有效页数会追加一页试读墙;翻页、目录
跳转、大纲的上界都统一收敛到可读范围,避免用户绕过热区跳转或朗读高亮跳进未授权页。

阅读进度与书签复用 RDPDFReaderPersistenceStore 已有的标注状态目录,新增
reader-state.json 承载,不需要宿主额外提供数据库表;RDPDFReaderPersistenceStore
同时实现 RDPDFReaderPersistence 协议对接这部分读写。
2026-08-14 12:13:04 +09:00
shenlei e01cbc169d 修复 EPUB 与 PDF 阅读器朗读交互
PDF 朗读的逐词回调会在同一页内持续触发高亮,原实现每次都调用翻页入口,使用户在朗读过程中反复看到页面转场。现仅在目标页变化时定位,并对朗读产生的跨页定位禁用动画,保留高亮刷新而不重复翻页。\n\nEPUB/TXT 此前只提供内容源,缺少将朗读进度回写到阅读器的会话层,无法从当前阅读位置开始朗读、随内容跨页及显示临时高亮。新增 EPUB 朗读会话,使用 href 与 UTF-16 偏移恢复位置;文本重排 EPUB 与 TXT 按实际页面定位并高亮,Web EPUB 则按章节安全定位以避免词级回调导致跳页。URL 阅读器同时提供可选会话入口,图片型阅读器保持不可朗读。\n\n已执行 ReadViewDemo 的 Debug Simulator 构建,结果为 BUILD SUCCEEDED。
2026-07-30 18:33:04 +09:00
shenleiandClaude Opus 5 d830311894 修复 PDF 仿真翻页模式下翻页后页面全白
打开普通 PDF 并使用仿真翻页阅读时,除首页外每翻一页都是纯白:没有页面
内容,也没有页面四周的衬底色。横向滚动与竖滑模式不受影响。样张
英汉大词典App需求说明.pdf 上第 2 到第 9 页无一例外。

根因是页面数据回来时找不到对应的视图。UIPageViewController 会通过
viewControllerBefore/After 提前构建相邻页的内容视图,构建时页面描述尚未
就绪,configure 发起异步 readerPage 请求后先返回一张空白页。描述返回后
acceptPageDescriptor 调用 refreshVisiblePage,而它经由
RDPDFReaderView.pageContentView(pageNum:) 定位视图,该方法在仿真翻页下
只检索 nativeCurlPageController.viewControllers,也就是已经上屏的 child。
预建的 child 此时还不在其中,图片因此从未被装配上去;翻页动画结束后又
没有任何路径重新 configure 该视图,白页就固定下来。此前偶尔能看到内容,
是 OCR 完成回调顺带触发了一次刷新,并非稳定行为。

改为按页码刷新该页的全部活动视图:控制器用弱引用表记录已创建的页面视图,
refreshVisiblePage 改名为 refreshPageViews(at:),除已上屏视图外一并装配
尚未上屏的预建视图,pageContentView 创建时即写入 tag 以便按页码匹配。
翻页落定时在 pageNum 回调中补一次装配,使内存告警清掉页面描述的场景也能
重新发起请求并恢复。另外把 image 为空的页面描述改按无效结果处理,走既有
的重试与失败重载入口,不再缓存出一张永远不会重试的白页。

新增 PDFPageTurnBlankPageTests 作为回归:翻页稳定后截屏统计画面中部深色
像素占比,白页为 0,扉页约 0.002,正文页在 0.01 以上,以 0.0005 为判定
阈值,覆盖仿真翻页正翻、仿真回翻和横向滚动三种路径。

验证:iPhone 17 Pro / iOS 26.4.1 模拟器执行 PDFPageTurnBlankPageTests、
PDFAnnotationTests、PDFDrawingModeTests、PageNavigationTests、
DisplayTypeTests 共 23 条用例,22 条通过。修复前仿真翻页第 2 到 9 页墨迹
占比全为 0.0000,修复后与横向滚动模式逐页吻合。唯一失败的
DisplayTypeTests.testDisplayTypeSwitchMidSession 属 EPUB 设置面板既有问题,
将本次改动还原后同样失败。文档补充了 Demo 因链接 FoundationModels 而必须
使用 iOS 26 及以上模拟器的说明。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-30 17:52:29 +09:00
shenandshen 85cf92161c Merge branch 'dev' of http://192.168.21.200:8418/4v5u09Z5a4Yuc/ReadViewSDK into dev 2026-07-27 21:54:56 +08:00
shenandshen 9392027106 更新阅读器功能与示例 2026-07-27 21:43:13 +08:00
shenlei 95cead5863 修复 PDF 阅读交互稳定性并统一项目技能管理
PDF 阅读器在慢速双指缩放、竖向滚动页高异步更新、页面请求超时和绘画橡皮擦等场景中,存在视口跳动、迟到结果被错误丢弃、缓存边界不明确及笔迹显示与持久化不同步的问题;同一本书的标注读取和并发写入也会产生不必要的磁盘访问或覆盖风险。\n\n调整缩放 inset 计算和竖向阅读锚点恢复,避免缩放变换被重复计入、真实页高到达时改变当前阅读位置。页面请求改为带 token 的超时重试机制,可在缓存窗口内接收有效迟到结果并提供失败重试入口;页面大图、OCR、笔迹和描述缓存统一按当前页前后两页收敛,PDF 标识改为完整内容 SHA-256,避免同名或相近文件复用错误阅读状态。\n\n绘画会话内按路径实时重绘,退出会话后使用按图层派生的位图缓存,确保橡皮擦即时作用于已提交笔迹;同时为笔迹持久化增加版本控制、为标注读写增加同步保护和内存快照,降低复用与并发场景下的状态错乱。\n\n将项目技能统一迁入 .agents/skills,并以 .claude/skills 相对软链接供 Claude Code 读取;新增详细 Git 提交技能,自动审查改动、生成中文提交说明并约束安全推送。

验证:所有项目技能通过 quick_validate;执行 xcodebuild -workspace ReadViewDemo/ReadViewDemo.xcworkspace -scheme ReadViewDemo -configuration Debug -sdk iphonesimulator CODE_SIGNING_ALLOWED=NO build,构建成功。
2026-07-24 14:40:02 +09:00
shenlei 68d9363f0a feat: optimize reader caching and document formats 2026-07-20 17:22:06 +09:00
shenandshen 52f803e8db fix: restore demo build and drawing interactions 2026-07-15 21:13:05 +08:00
shenleiandClaude Fable 5 1422461224 将 PDF 成品阅读控制器下沉为 RDPDFReaderView SDK,并修复手机横屏单页连续竖滑
SDK 化收尾:
- 新增 RDPDFReaderView 本地 pod(阅读容器、成品控制器、划线/注释、画笔、
  目录/设置面板、主题与持久化契约),Demo 精简为 PDFKit 页面提供者 + 持久化宿主
- Podfile/工程接入 RDPDFReaderView 与 SnapKit,示例书改用 PDF 阅读器示例文件

手机横屏单页竖滑修复:
- cell 高度改为宽度适配后的纸张高度(sizeForItemAt + 宿主按页提供纵横比),
  纵向超出一屏的内容由外层 collectionView 连续滚动承接,不再被裁掉
- 页面内部不再开启同向嵌套的兜底竖向拖动,修复外层滚动被吞、无法滚到下一页
- 修复 applyContentSize 先评估拖动开关后写 contentSize 的顺序缺陷
- 页码按视口中心命中 cell 计算,补 didEndDragging 兜底;旋转重锚点与
  transitionToPage 改用真实布局位置
- 横竖屏同为竖滑时也重建 cell 并刷新全部可见页的适配配置
- 横屏单页点击不再跳页,只显隐工具栏;翻页交给连续竖滑

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 18:49:44 +09:00
shenleiandClaude Fable 5 a17164d1a9 将 PDF 注释编辑器、笔记列表、目录/设置面板与面板呈现下沉到 SDK
SDK 新增:
- RDPDFReaderAnnotationEditorViewController:注释输入页(UI 与 EPUB 编辑器一致)
- RDPDFReaderAnnotationListViewController:笔记列表(全部/注释/高亮筛选、滑动删除)
- RDPDFReaderNavigationPanelViewController:目录/书签/缩略图面板容器
- RDPDFReaderSettingsPanelViewController:亮度/翻页方式/主题设置面板
- RDPDFReaderPanelPresenter + 转场/呈现控制器:底部面板统一呈现,
  转场代理生命周期由被呈现控制器持有,宿主无需保存引用
- RDPDFReaderThemeOption:SDK 自有主题模型,面板与编辑器不再依赖 EPUB 主题类型
- UIColor(rdPDFHexString:) 公开,并消除覆盖层内的私有重复实现

Demo 侧:
- 删除 PDFDemoAnnotationUI.swift 整个文件
- 删除 PDFDemoNavigationViewController / PDFDemoSettingsViewController /
  面板转场三个类(约 410 行),改为调用 SDK 组件
- ThemePreset 增加到 RDPDFReaderThemeOption 的映射

无障碍标识全部保留,UI 自动化不受影响。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 10:51:51 +09:00
shenleiandClaude Fable 5 1bde945d36 将 PDF 划线/注释交互完整下沉到 SDK 库
- RDPDFReaderPageView:完整页面视图移入 SDK(缩放画布、文字选择层、
  选区放大镜、无障碍视口),并内置与 EPUB 一致的两套系统编辑菜单:
  选区菜单(复制/划线/注释)、已有划线菜单(复制/注释|删除注释/删除划线)
- RDPDFReaderPageViewDelegate:宿主只通过代理做数据持久化与打开业务界面
- 修复划线命中判定:点击点先归一化再与标注比例坐标比较
- 修复 tappedHighlight 残留导致选区菜单项被错误过滤的问题
- 主题应用改为纯颜色入参,SDK 不依赖 EPUB 主题类型
- RDPDFReaderHighlightOverlayView 恢复为纯绘制层,点击交互统一由页面视图处理
- Demo 删除 PDFDemoPageView(约 290 行),改为实现代理回调

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-15 10:33:43 +09:00
shenleiandClaude Haiku 4.5 5a19cfde14 refactor: move highlight menu logic from Demo to SDK library
Add RDPDFReaderPageView as base page view class in SDK:
- Handles all highlight menu interactions and display
- Provides RDPDFReaderPageViewDelegate for menu action callbacks
- Unifies with EPUB architecture: RDEPUBTextContentView pattern
- Reduces code duplication for applications using the SDK

Benefits:
- Reusable menu interaction logic across all PDF apps
- Consistent architecture with EPUB reader
- Single responsibility principle (UI in library, persistence in app)
- Backward compatible (existing code continues to work)

Applications now implement RDPDFReaderPageViewDelegate to:
- Respond to highlight menu actions
- Handle data persistence
- Refresh UI after changes

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-15 10:19:54 +09:00
shenleiandClaude Haiku 4.5 d56e99a83f add tap-on-highlight menu with copy/annotate/delete actions, matching EPUB behavior
- Add RDPDFReaderAnnotationMenuAction and RDPDFReaderExistingHighlightMenuAction enums to PDF contracts
- Enable highlight overlay view to detect tap gestures and report tapped highlights
- Implement existing highlight menu in Demo page: copy text, add/edit annotation, delete annotation, delete underline
- Handle menu actions in PDFDemoReaderViewController to persist changes
- Ensure highlight tap detection doesn't interfere with text selection

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-15 10:06:02 +09:00
shenleiandClaude Haiku 4.5 fed34da246 unify PDF and EPUB reader: convert highlights to underlines, improve annotation UI, change paging from horizontal to vertical
- Convert PDF highlights from filled rectangles to underlines matching EPUB style
- Update PDF annotation editor with EPUB-style design: gold sidebar rail, semi-transparent background, improved spacing and shadows, dark mode support
- Change PDF page-curl paging from left-right horizontal to up-down vertical: update gesture recognition and tap regions accordingly

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
2026-07-15 10:01:23 +09:00