iOS Epub阅读器改造记录

六个月前在这个YHEpubDemo阅读器的基础上做了一些优化,这里做一下记录。

1.首行缩进修复

由于分页的存在,新的一页的首行可能是新的一行,则应该缩进;也可能是前面一页段落的延续,这时候不应该缩进。YHEpubDemo基于XDSReader,XDSReader目前存在新页首行没有缩进的问题。

修复方案如下:

原来预排版分页后将每一页的富文本设置给XDSReadView,这样就失去了排版的连续性。现在改为将整个章节的富文本设置给XDSReadView,并且对该页需要显示的文本范围进行布局。

在XDSReadView.m的reloadView底部加上以下代码:

CGRect rect = UIEdgeInsetsInsetRect(self.readTextView.bounds, self.readTextView.edgeInsets);DTCoreTextLayoutFrame *layoutFrame = [self.readTextView.layouter layoutFrameWithRect:rect range:_pageRange];self.readTextView.layoutFrame = layoutFrame;

因为前面我们已经给readTextView设置了整个章节的富文本:

self.readTextView.attributedString = self.readAttributedContent;

因此我们这里要根据布局区域的大小和布局文本的范围,使用layouter来产生一个layout frame。这样产生的布局是具有连续性的。如果仍然使用原来分页的方式的话,需要判断当前页第一行开始处,是否位于上一页的段落中。如果不在其中,而是新的段落,就要获取上一页段落的样式中的headIndent,将其设置给当前页第一行样式中的firstLineHeadIndent。

2.CSS rem修复

XDSReader基于DTCoreText,DTCoreText有自己的css和HTML解析器,但是不支持css的rem特性,这样会导致字体大小有问题。由于DTCoreText没有提供root element上下文,目前暂时将rem当em处理,虽然会有一些误差,但不至于字体大小变1pt。

3.树形目录

根据epub规范,我们是可以解析获得任意多级的目录的。考虑到目录可以折叠展开,当我们获得了树形数据结构后,我们可以使用BFS(宽度优先遍历)来实现目录的打平:

- (void)reloadData
{self.catalogs = [NSMutableArray arrayWithArray:CURRENT_BOOK_MODEL.catalog.children];NSMutableArray *q = [NSMutableArray arrayWithArray:CURRENT_BOOK_MODEL.catalog.children];while (q.count > 0) {XDSCatalogueModel *top = q[0];[q removeObjectAtIndex:0];if(top.isExpand){[q addObjectsFromArray:top.children];NSInteger idx = [self.catalogs indexOfObject:top];if(idx == NSNotFound){idx = -1;}[self.catalogs insertObjects:top.children atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(idx+1, top.children.count)]];}}[self.tableView reloadData];
}

首先我们将一级目录节点加入临时数组和结果数组,如果当前临时数组数组不为空,则取出第一个,并且从临时数组中移除。如果这个节点是展开的,就把这个节点的子节点加入临时数组。现在我们从结果数组中找到这个节点的位置,将它的子节点按顺序插入后面。像这样往复前面的操作,直到临时数组为空为止。最终我们得到了一个平坦的列表。

4.增加页码

增加页码就是在预排版和分页时,需要记录每一个章节的页码范围,每一页的文字范围等,然后据此计算页面所在的页码,以及页码所在的文字范围等。

5.textblock背景色修复

源码中会给textblock设置一个难看的深蓝色的背景色,在我们的修复中会首先尝试获取textblock的背景色,没有的话才设置为白色:

 CGColorRef color = [textBlock.backgroundColor CGColor];if(!color){color = [[UIColor whiteColor] CGColor];}

6.其他

另外对阅读进度记录,添加note也做了一些修复。增加了水平滚动翻页类型。

最终的效果:

 

 源码:GitHub - Mamong/YHEpubDemo: Epub 阅读器

 后续考虑使用Swift重写,并将epub解析部分抽取出来。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/92813.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

flutter 常见的状态管理器

flutter 常见的状态管理器 前言一、Provider二、Bloc三、Redux四、GetX总结 前言 当我们构建复杂的移动应用时,有效的状态管理是至关重要的,因为应用的不同部分可能需要共享数据、相应用户交互并保持一致的状态。Flutter 中有多种状态管理解决方案&#…

Oracle和MySQL有哪些区别?从基本特性、技术选型、字段类型、事务、语句等角度详细对比Oracle和MySQL

导航: 【Java笔记踩坑汇总】Java基础进阶JavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成在线MySQL高级篇设计模式面试题汇总源码_vincewm的博客-CSDN博客 目录 一、基本区别 1.1 基本特性 1.2 Oracle和MySQL如何做技术选型? 1.3 RDBM…

经验分享:企业数据仓库建设方案总结!

导读 在企业的数字化转型浪潮中,数据被誉为“新时代的石油”,而数据仓库作为数据管理与分析的核心基础设施,在企业的信息化建设中扮演着重要的角色。本文将深入探讨企业数据仓库建设过程中所遇到的问题以及解决经验,为正在筹备或…

Spring对象装配

在spring中,Bean的执行流程为启动spring容器,实例化bean,将bean注册到spring容器中,将bean装配到需要的类中。 既然我们需要将bea装配到需要的类中,那么如何实现呢?这篇文章,将来阐述一下如何实…

无涯教程-Perl - setservent函数

描述 在第一次调用getservent之前,应先调用此函数。 STAYOPEN参数是可选的,在大多数系统上未使用。当getservent()检索服务数据库中下一行的信息时,然后setervent设置(或重置)枚举到主机条目集的开头。 语法 以下是此函数的简单语法- setservent STAYOPEN返回值 此函数不返…

stack 、 queue的语法使用及底层实现以及deque的介绍【C++】

文章目录 stack的使用queue的使用适配器queue的模拟实现stack的模拟实现deque stack的使用 stack是一种容器适配器&#xff0c;具有后进先出&#xff0c;只能从容器的一端进行元素的插入与提取操作 #include <iostream> #include <vector> #include <stack&g…

矢量绘图UI设计软件Sketch mac中文版软件说明

Sketch mac是一款适用于 UI/UX 设计、网页设计、图标制作等领域的矢量绘图软件。 Sketch mac软件特点 1. 简单易用的界面设计&#xff1a;Sketch 的用户界面简洁明了&#xff0c;使得用户可以轻松上手操作&#xff0c;不需要复杂的学习过程。 2. 强大的矢量绘图功能&#xff1a…

驱动day3

思维导图 练习 1.编写LED灯的驱动&#xff0c;可以控制三个灯&#xff0c;应用程序中编写控制灯的逻辑&#xff0c;要使用自动创建设备节点机制 head.h #ifndef __HEAD_H__ #define __HEAD_H__typedef struct {unsigned int MODER;unsigned int OTYPER;unsigned int OSPEEDR…

SharkTeam:Worldcoin运营数据及业务安全分析

Worldcoin的白皮书中声明&#xff0c;Worldcoin旨在构建一个连接全球人类的新型数字经济系统&#xff0c;由OpenAI创始人Sam Altman于2020年发起。通过区块链技术在Web3世界中实现更加公平、开放和包容的经济体系&#xff0c;并将所有权赋予每个人。并且希望让全世界每一个人都…

Android中如何不编译源生模块

如果想让自己的app 替换系统的app 比如使用闪电浏览器替换系统的Browser 首先把闪电浏览器放到 vendor/rockchip/common/apps Android.mk LOCAL_PATH : $(call my-dir) include $(CLEAR_VARS)LOCAL_MODULE : Lightning LOCAL_SRC_FILES : $(LOCAL_MODULE).apk LOCAL_MODULE_C…

Unity如何把游戏导出成手机安装包

文章目录 前言使用环境步骤添加场景构建APK 前言 本文章主要演示了&#xff0c;如何将制作好的游戏&#xff0c;导出成APK&#xff0c;安装到手机上。 使用环境 Unity2022。 步骤 首先打开你的项目&#xff0c;然后选择菜单栏的“File” > “Build Settings…”&#xf…

windows权限维持—SSPHOOKDSRMSIDhistorySkeletonKey

windows权限维持—SSP&HOOK&DSRM&SIDhistory&SkeletonKey 1. 权限维持介绍1.1. 其他 2. 基于验证DLL加载—SPP2.1. 操作演示—临时生效2.1.1. 执行命令2.1.2. 切换用户 2.2. 操作演示—永久生效2.2.1. 上传文件2.2.2. 执行命令2.2.3. 重启生效 2.3. 总结 3. 基…

c语言每日一练(8)

前言&#xff1a;每日一练系列&#xff0c;每一期都包含5道选择题&#xff0c;2道编程题&#xff0c;博主会尽可能详细地进行讲解&#xff0c;令初学者也能听的清晰。每日一练系列会持续更新&#xff0c;暑假时三天之内必有一更&#xff0c;到了开学之后&#xff0c;将看学业情…

日常BUG——SpringBoot模糊映射

&#x1f61c;作 者&#xff1a;是江迪呀✒️本文关键词&#xff1a;日常BUG、BUG、问题分析☀️每日 一言 &#xff1a;存在错误说明你在进步&#xff01; 一、问题描述 SpringBoot在启动时报出如下错误&#xff1a; Caused by: java.lang.IllegalStateExceptio…

springboot启动忽略某些类

springboot启动忽略某些类 描述解决方案单拉一个提交&#xff0c;把所有的涉及kafka消费的都不注入容器通过配置ComponentScan的excludeFilters配置了不生效后续处理改之前改之后解释 总结 拆分环境 感触解决实现demo参考 描述 目前我这的开发环境和测试环境数据库是两份&#…

Java真实面试题,offer已到手

关于学习 在黑马程序员刚刚开始的时候学习尽头非常足&#xff0c;到后面逐渐失去了一些兴趣&#xff0c;以至于后面上课会出现走神等问题&#xff0c;但是毕业时后悔晚矣。等到开始学习项目一的时候&#xff0c;思路总会比别人慢一些&#xff0c;不看讲义写不出来代码。 建议…

virtualBox桥接模式下openEuler镜像修改IP地址、openEule修改IP地址、openEule设置IP地址

安装好openEuler后,设置远程登入前,必不可少的一步,主机与虚拟机之间的通信要解决,下面给出详细步骤: 第一步:检查虚拟机适配器模式:桥接模式 第二步:登入虚拟机修改IP cd /etc/sysconfig/network-scripts vim ifcfg-enpgs3 没有vim的安装或者用vi代替:sudo dnf …

设计模式(6)原型模式

一、介绍 Java中自带的原型模式是clone()方法。该方法是Object的方法&#xff0c;native类型。他的作用就是将对象的在内存的那一块内存数据一字不差地再复制一个。我们写简单类的时候只需要实现Cloneable接口&#xff0c;然后调用Object::clone方法就可实现克隆功能。这样实现…

[oneAPI] 图像分类CIFAR-10

[oneAPI] 图像分类CIFAR-10 图像分类参数与包加载数据模型训练过程结果 oneAPI 比赛&#xff1a;https://marketing.csdn.net/p/f3e44fbfe46c465f4d9d6c23e38e0517 Intel DevCloud for oneAPI&#xff1a;https://devcloud.intel.com/oneapi/get_started/aiAnalyticsToolkitSam…

解决内网GitLab 社区版 15.11.13项目拉取失败

问题描述 GitLab 社区版 发布不久&#xff0c;搭建在内网拉取项目报错&#xff0c;可能提示 unable to access https://github.comxxxxxxxxxxx: Failed to connect to xxxxxxxxxxxxxGit clone error - Invalid argument error:14077438:SSL routines:SSL23_GET_S 15.11.13ht…