美文网首页项目以及封装好东西iOS Core Text
iOS基于CoreText实现的电子书阅读器

iOS基于CoreText实现的电子书阅读器

作者: 启发禅悟 | 来源:发表于2016-10-06 21:25 被阅读4991次

    之前写小说类相关的应用,需要电子书阅读器,在网上找了很久,觉得还是https://github.com/GGGHub/Reader 同学的最好用,所以就拿这个用了。
    不过后来发现里面的书签,笔记的定位功能,以及字体变化等功能有点问题,造成阅读者的不愉快,所以特意Fork了一个版本做了相应的修改,大家如果有类似的问题,可以试试我修改后的版本,在这里
    https://github.com/Inspirelife96/Reader

    如果大家有更好的阅读器,请推荐给我,万份感谢:)

    Reader


    基于Core Text实现的iOS客户端的电子书阅读器。</br>
    支持ePub与text格式


    2016.10.02 更新 (我做的修改)

    针对text小说的bug fix。

    1. 当字体变化时,小说有时候不会自动调整界面。
    2. 当字体变化时,还有小说的书签,笔记定位不准确,甚至程序崩溃。3.

    大概思路:

    1. 当字体变化时,所有小说的章节都会基于新的字体重新调整,分页等。
    2. 记录笔记/书签文字开始位置的在整个章节中的下标位置,笔记/书签定位时,基于当前的字体分页,看当前的下标位置是否坐落在哪一页中,然后跳转到那一页。

    2016.06.16 更新 (以下都是LiSiYuan写的,非常好的库,我自认为没有他的水平,大家可以好好学习)

    添加对ePub格式的支持


    部分功能实现效果

    Paste_Image.png

    关于Reader</br>

    1. 可以自动提取章节并生成目录
    2. 选取一段文字可进行复制,做笔记等功能
    3. 保存阅读进度,即使退出应用也可以继续之前的阅读
    4. 更改字体大小,进度跳转,主题更换等功能
    5. 支持txtePub格式的电子书文件

    安装与使用

    安装

    1. Reader目录下的所有文件都添加到工程中</br>
    2. 由于解压ePub文件,需要用到开源的.c文件用于解压缩。所以使用时如果项目中有.pch文件参考本项目中.pch文件写法</br>
    #ifdef __OBJC__
    //在.pch中这里写引用的.h文件与宏
    #endif
    

    3.需要导入libz.tbd

    使用

    text文件</br>

       LSYReadPageViewController *pageView = [[LSYReadPageViewController alloc] init];
        NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"mdjyml"withExtension:@"txt"];
        pageView.resourceURL = fileURL;    //文件位置
        pageView.model = [LSYReadModel getLocalModelWithURL:fileURL];  //阅读模型
        [self presentViewController:pageView animated:YES completion:nil];
    

    ePub文件</br>

       LSYReadPageViewController *pageView = [[LSYReadPageViewController alloc] init];
        NSURL *fileURL = [[NSBundle mainBundle] URLForResource:@"细说明朝"withExtension:@"epub"];
        pageView.resourceURL = fileURL;    //文件位置
        pageView.model = [LSYReadModel getLocalModelWithURL:fileURL];  //阅读模型
        [self presentViewController:pageView animated:YES completion:nil];
    

    提示

    之前安装过的下载最新版,应把之前安装的卸载后再安装

    说明

    对于有图片和定制样式的epub文件只显示纯文本信息,因为对epub每个章节的html文件直接转成字符串来处理,css样式与epub自带的本地图片没有做处理。

    相关文章

      网友评论

      • Mannyao:为啥reader里面的是mrc 却没有报错,你demo上的也是rac环境,我拉进我的项目 一些release 和 retain 就开始报错了
      • yikeshuu:大神你好,我按照流程导入目录文件添加ilbz.td,copy了PCH文件, 我在other linker flags 下添加-lxml2 ,search paths下添加了${SDK_ROOT}/usr/include/libxml2,还是提示'libxml/tree.h' file not found ,请问哪里还漏了什么吗?:sweat:
      • 酱爆番茄:集成不了啊 按步骤来的都是 一堆错误
        酱爆番茄:@启发禅悟 不能打开沙盒内文件么 只能打开bundle?
        酱爆番茄:@启发禅悟 解决了都 谢谢
        启发禅悟:@布拉德建刚 出问题网上找找如何解决
      • 楚简约:有同时支持txt PDF epub这三种格式的阅读器吗,推荐下
      • 3fdb581ec682:楼主的阅读器做的很好,但是看了好久代码思绪有点乱,能不给我讲讲大概qq1393729501,具体细聊
        启发禅悟:@南海一页扁舟 呃。不是我写的哦。我只是改了一点代码。看原作者的github、我文章里有些。我也好久没看了。没法给你讲了
      • 3fdb581ec682:问个问题关于epub解析的话,我怎么知道epub每个节点名字怎么查看,epub解析到底该怎么做,谢谢急急急
      • 3fdb581ec682:有个问题想请教大神,为啥第一次进来加载epub文件可以显示出来,第二次进来就是空的背景色,没有文字
        启发禅悟:@这个熊孩子不太冷 没有。没时间更新这个了。你自己研究看看吧。不好意思哦
        这个熊孩子不太冷:你好,问题解决了吗?有优化的demo吗
        启发禅悟:@南海一页扁舟 epub这部分我没有研究过。你去看看原作者的github,我之前有看到关于epub他有更新过。https://github.com/GGGHub/Reader。如果还是不行,你可能需要自己调试看看问题的症结所在。
      • LinVilk:楼主,iOS11菜单栏出不来,您看了吗?指教一下
        启发禅悟:@LinVilk 哦。我还没有看。简单扫一眼吧。如果简单我就改了,如果需要花很多时间,可能就得你自己研究了。
        LinVilk: @启发禅悟 我也是正在看,我想着问问您改了没
        启发禅悟:@LinVilk 还没看。你可以自行修改吗?
      • 唐长老々:感谢您的分享,您的阅读器对我帮助很大,不过想请教一下,为什么在iOS11系统上不显示上边栏和下边栏?您可以看看优化下吗?
        启发禅悟:@唐长老々 :+1:
        唐长老々:我找了半天发现注掉
        #pragma mark - Menu View Delegate
        -(void)menuViewDidHidden:(LSYMenuView *)menu
        {
        _showBar = NO;
        // [self setNeedsStatusBarAppearanceUpdate];
        }
        -(void)menuViewDidAppear:(LSYMenuView *)menu
        {
        _showBar = YES;
        // [self setNeedsStatusBarAppearanceUpdate];

        }
        这两行代码就可以正常显示了,但是状态栏不出来了!这个用另一种方法显示状态栏就好了!谢谢楼主,已解决
      • LinVilk:楼主,您好,我想问一下在您这个Demo基础上添加epubCSS样式与自带的本地图片处理!麻烦您给个缪斯?谢谢!
        启发禅悟:@LinVilk https://github.com/GGGHub/Reader这个是原作者。你要不去他的github上问问?我只是修改了txt部分debug
        LinVilk: @启发禅悟 原作者是谁啊?我看您里面有那个一系列得解析,只是您没有用到,
        启发禅悟:@LinVilk 我没研究过epub部分。要不你问问原作者?或者自己研究下代码?
      • 老顽童_0c44:连接可以用吗
        老顽童_0c44:@启发禅悟 我用不了 只能本地 连接可以显示但是功能点击就崩
        启发禅悟:@老顽童_0c44 可以用啊。你不能?
      • chongchongge:你好,我能问下这个用来解析EPUB3实现多媒体播放该怎么做?
        chongchongge:@启发禅悟 :sob:好吧,比较复杂这玩意
        启发禅悟:@chongchongge 不好意思,没研究过这块内容
      • 幻夏灬:我想请问一下楼主, 我的每一个章节都是一个独立的url, 小说在服务器里是按单章节存的, 能不能帮忙给提供一个思路?
        Oopsbabyiloveyo:请问我用的是E_Reader, 但是现在所有的书都一直用存储的哪一个章节和页数, 怎么能做到每本书存的章节和页码数不一样呢
        幻夏灬:@启发禅悟 我去看一下, 谢谢楼主了
        启发禅悟:按章节的阅读器请参考这个类库https://github.com/TigerWf/WFReader
      • 韦胖:请问下我导入libzxml2.2.tbd以后提示找不到然后我修改paths以后 。爆了一堆系统错误自带库错误 请问下怎么解决
        启发禅悟:@育碧正版受害玩家 好的。谢谢
        韦胖:@启发禅悟 你好 。谢谢你的回复
        已经解决了 mrc需要加-fno-objc-arc
        启发禅悟:@育碧正版受害玩家 没有具体的错误,我也不知道怎么帮你查找。可能的,一是你的pch文件没有按照文档说明的写。二是有人提到other linker flag的问题。你去build settings查找下other linker flag 设置为 -lxml2。我猜想是第二个问题造成的。你没有链接xml2库。链接上就可以了
      • 小王子sl:现在报runtime错误 集成不了
        小王子sl:额。。。。是other linker flags的问题 这个你们应该写在readme
        小王子sl:@启发禅悟 三步都确认了 还是不行 报<libxml/tree.h> file not found 然后加上${SDKROOT}/usr/include/libxml2 还是有36个xml的错误
        启发禅悟:你下载的demo能够运行么?如果可以,那么你集成的时候出runtime错误,你要自己耐下心来研究下,自己集成的时候有遗漏什么。比如文档里提到的安装与集成的步骤做了吗?
        ##安装与使用 ###安装
        将Reader目录下的所有文件都添加到工程中
        由于解压ePub文件,需要用到开源的.c文件用于解压缩。所以使用时如果项目中有.pch文件参考本项目中.pch文件写法
        #ifdef __OBJC__
        //在.pch中这里写引用的.h文件与宏
        #endif
        3.需要导入libz.tbd库
      • LinVilk:楼主您好,想请教一下怎么在最后一页跳转页面啊?我想做免费和收费章节的
        启发禅悟:@LinVilk 没有越界啊,demo,以及我自己发布的应用,测试下来都没有最后一页向右滑动发生越界问题。你可以告知我你是怎么发生数组越界的问题的吗?
        你希望一个一个章节load的?我印象中还有一个reader库,做的是按章节load的,我找找啊。找到了,这个https://github.com/TigerWf/WFReader,你如果要按章节load,然后后面的某些章节做成VIP才能阅读,可以参考这个试试。
        LinVilk:@启发禅悟 在最后一页向右滑动的时候,会出现数组越界的问题,同时还向为问下,怎么添加一个章节为一个文件的书哪?请您不吝赐教
        启发禅悟:@LinVilk 没明白你的问题。要在最后一页跳转到别的vc?自己添加事件咯,判断是不是最后一页,然后处理。
      • 7074d5828d93: 大神你好,你的demo中是将text文件全部加载进内存中的,并且刷新字体大小等操作会重新再刷一遍。文件小还好,若是文件稍微大一点的话,会不会有性能问题呢?不知道您是否有考虑过这个问题
        启发禅悟:@兰州_52d8 评论里有人做了一些改进,你可以和他讨论下。他的策略是更新字体时只更新一个章节而不是全部文章。你可以看看。
      • MWRTB:你好,请问下我按照这个方式截取的文字 没有填充满Label,大概只有四分之三的样子,大概是什么原因造成的呢?

        NSMutableDictionary *dict = [NSMutableDictionary dictionary];
        dict[NSFontAttributeName] = font17;
        CGRect bounds = CGRectMake(0, 0, viewWidth, viewHeight);

        NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] initWithString:allContentText];

        [attrString setAttributes:dict range:NSMakeRange(0, attrString.length)];

        CTFramesetterRef frameSetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef) attrString);

        CGPathRef path = CGPathCreateWithRect(bounds, NULL);

        CTFrameRef frame = CTFramesetterCreateFrame(frameSetter, CFRangeMake(currentInnerOffset, 0), path, NULL);

        CFRange range = CTFrameGetVisibleStringRange(frame);

        启发禅悟:@ws1227 整本。因此性能差
        00fce043cf44:楼主切换字体大小的时候是只刷新本章的还是整本的?
        启发禅悟:@吃少了要长胖 不太熟悉这块,我答不上来。抱歉哦。
      • 开源大同:楼主,你好,我使用epub读取书后关闭,再次打开,有时读取不到历史记录,都是空白页。但是_model.chapters[chapter].chapterpath是存在的,转换后的html字符串就是空@“”。NSString *html = [[NSString alloc] initWithData:[NSData dataWithContentsOfURL:[NSURL fileURLWithPath:_model.chapters[chapter].chapterpath]] encoding:NSUTF8StringEncoding],怎么破?
        启发禅悟:@开源大同 主要好久没看这个代码了。你好好debug下,肯定能找出问题的所在的。加油。
        开源大同:@启发禅悟 哦哦,好的,不过还是谢谢你
        启发禅悟:@开源大同 我只改了txt部分。epub我没有看。。。也没有改
      • 最后还是个农:楼主,知道如何修改字体颜色吗?找了两个小时了,也没有看到,来分享下:smile:
        启发禅悟:@最后还是个农 :blush::blush::blush:
        最后还是个农:已找到,在LSYReadConfig中有fontColor这个属性,因为是保存到本地的,修改后要卸载重新装,才有变化
      • 施主小欣:楼主~我又来了。。碰到了吃书的现象 求破。第一页字体放大或缩小后多(少)出的字并没有在第二页显示。求楼主大大给一个思路
        启发禅悟:@施主小欣 告诉我具体的步骤,在demo中怎么复现这个问题?
        施主小欣:下载下来的Demo就有这种现象……
        启发禅悟:@施主小欣 吃书问题我特意解决过的。测试demo有吃书现象吗?还是你有其他特殊的情况?
      • 最后还是个农:您好,遇到点问题请教下:
        有一个txt文件,在文件的开头有目录列表如下:
        第001回 灵根育孕源流出   心性修持大道生
        第002回 悟彻菩提真妙理   断魔归本合元神
        第003回 四海千山皆拱伏   九幽十类尽除名
        第004回 官封弼马心何足   名注齐天意未宁
        第005回 乱蟠桃大圣偷丹   反天宫诸神捉怪
        第006回 观音赴会问原因   小圣施威降大圣
        第007回 八卦炉中逃大圣   五行山下定心猿
        第008回 我佛造经传极乐   观音奉旨上长安
        附  录 陈光蕊赴任逢灾   江流僧复仇报本。。。。。
        在正文的时候也有:
        第一回 灵根育孕源流出 心性修持大道生
        诗曰:
        混沌未分天地乱,茫茫渺渺无人见。
        自从盘古破鸿蒙,开辟从兹清浊辨。

        这样就造成目录解析错误,这块您了解吗?
        启发禅悟:@最后还是个农 查找下seperateChapter方法,里面定义了查找段落标题的正则表达式。你可以试着去调整下。不过像你描述的,目录列表在文件头上有额外的列表,此时可能你需要考虑下txt文件里是不是把这一部分去掉?否则还真的很难处理
      • 最后还是个农:谢谢分享
        最后还是个农:@启发禅悟 我做了如下修改,暂时没有出现bug,您帮看看有没有什么潜在问题:
        在LSYReadPageViewController.m文件中,修改设置字体回调方法:
        -(void)menuViewFontSize:(LSYBottomMenuView *)bottomMenu
        只更新当前章节的字体,移除for循环:
        [_model.chapters[_chapter] updateFont]。
        在触发-readViewWithChapter:page:方法的位置,如果是回到上一章节,就更新上一章节的字体:
        例如: CatalogViewController Delegate中的
        -(void)catalog:(LSYCatalogViewController *)catalog didSelectChapter:(NSUInteger)chapter page:(NSUInteger)page
        添加 [_model.chapters[chapter] updateFont];
        在Menu View Delegate中的-(void)menuViewJumpChapter:(NSUInteger)chapter page:(NSUInteger)page中添加:
        [_model.chapters[chapter] updateFont];
        在PageViewController DataSource中的
        - (nullable UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController中添加
        if (_pageChange==0) {
        _chapterChange--;
        #warning marl --- *******
        [_model.chapters[_chapterChange] updateFont];// 添加的代码
        _pageChange = _model.chapters[_chapterChange].pageCount-1;
        }
        您对代码整体更熟悉,帮忙看看,是否存在什么潜在问题。
        最后还是个农:想要优化下字体切换,您有什么好的思路吗?
        启发禅悟:@最后还是个农 :grin::grin::grin:
      • __枫__:您好,想问一下变更字体大小出现卡顿的问题您解决了吗?
        __枫__:@启发禅悟 好的,谢谢
        启发禅悟:@Mr_怪蜀黎 没有。因为字体调整不会是非常平凡的操作,所以暂时没考虑去调整性能。推荐你在字体调整时添加一个忙碌的进度提示用户
      • 嘻哈猴零:切换字体大小时间非常卡顿是什么问题
        启发禅悟:@嘻哈猴零 考虑到换字体不是一个非常频繁发生的操作,所以,暂时我没去特别考虑优化。你可以考虑在空闲时间提前把不同字体分页的结果提前计算并缓存。或者在变化字体时添加一个等待进度条。
        嘻哈猴零:@启发禅悟 有什么优化办法吗,像qq阅读之类的切换很流畅,就是不知道怎么解决的
        启发禅悟:@嘻哈猴零 是的。性能不好。因为改变字体会全部重新计算分页。以及标签等位置,非常耗计算
      • 施主小欣:楼主好~我是小白一个,在引用demo的时候报错while building module uikit imported from...等长达23个报错信息,库我也引用了,查了一些报错信息的资料也没有解决,希望楼主能点化我~
        启发禅悟:@施主小欣 可以用NSUrlSession (或者其他第三方网络下载库,例如AFNetwork)进行异步下载,将URL对应的小说以NSData的格式存储在本地(可以是Documents目录或者Cache)。异步下载完成后再去阅读这个下载好的小说
        施主小欣:@启发禅悟 现在就已经搞定啦…蟹蟹楼主这么晚还回我…:grin: 这里还想向楼主求一条思路,如果后台给我的事是url的txt文本我应该怎么处理呀?怎么缓存到本地呢?
        启发禅悟:@施主小欣 我在国外,可能要下个礼拜才能帮你看。你可以自己先尝试下能不能解决吧。 看看到底少了什么库,再看看怎么解决。
        相信明天你就自己搞定了。或者只能等我回国咯。
      • 范鑫:epub 文章拖动快进进度条 不久就会崩溃 是什么原因?
        刘振杰:同问
      • 46714177b9a0:点击翻页,快速点击会很卡顿,而且左侧经常性黑了
      • 经天X纬地:楼主,我发现了一个bug,虽然你对原demo进行改进吧字体大小调整改进了,但是有个新的问题就是字体调整后内容不会随着改变,比如把字体调大了,原来一个页面能显示100字,现在就显示80字,正常应该是会把剩下的20字在下一页补上,但是事实是没有的,这样就导致内容显示缺失了
        经天X纬地:@启发禅悟 嗯嗯,我后来也是用这种方式实现的,感谢楼主
        启发禅悟:关于改变颜色,我最先想到的是仿造FontSize的逻辑。
        -(void)changeFont:(UIButton *)sender
        {

        if (sender == _increaseFont) {

        if (floor([LSYReadConfig shareInstance].fontSize) == floor(MaxFontSize)) {
        return;
        }
        [LSYReadConfig shareInstance].fontSize++;
        [LSYReadConfig shareInstance].fontColor = [UIColor redColor];
        }
        else{
        if (floor([LSYReadConfig shareInstance].fontSize) == floor(MinFontSize)){
        return;
        }
        [LSYReadConfig shareInstance].fontSize--;
        [LSYReadConfig shareInstance].fontColor = [UIColor greenColor];
        }

        if ([self.delegate respondsToSelector:@selector(menuViewFontSize:)]) {
        [self.delegate menuViewFontSize:self];
        }
        }

        我在这个函数里加了颜色的设置,字体变大,颜色变红,字体变小,颜色变绿。效果是立刻变色的。
        所以你可以研究下, [self.delegate menuViewFontSize:self];具体做了什么事情,能够让颜色,自理立刻刷新。大多应该是调用了updateReadModelWithChapter这个函数的结果。(我猜的,具体没有看)。

        简单粗暴的话,就是把FontSize变化的逻辑copy一边,然后修改为字体颜色。当然中间可能会有坑。
        所以你仔细研究下吧。
        启发禅悟:这个问题应该解决了吧。我记得我特意改过这个“吃书”的问题。现在字体大小变化之后,会重新计页数,然后重新显示所在页的内容。所以内容可能会和你当前看的内容不一致,但不应该有吃书问题。
        举个例子,你当前字体是14,阅读的是第一章第10页的内容。然后把字体变成28(举个例子哦,假设字体翻倍,一页显示的内容减半),这时候还是显示字体28状态下的第10页的内容,也就是字体14第5页的内容。并不是你之前阅读的内容了。

        我测了下demo的例子没有吃书的现象啊。我指的是TXT格式,epub我没有用过,不清楚情况。
      • hello_kity:你好我想请问加载网络的url的时候怎么加载啊 这个是下载到本地的~~
        启发禅悟:@hello_kity 你想想,网页上的在线阅读,也是http请求然后拿到数据才能在网页上显示的。本质也是下载。如果你本身已经是网页版的小说,分好了页了。那直接用webview显示网页就好了。如果你本身小说是一个个txt文件,那么把文件放服务器,然后用户点击这个小说观看是,你可以用NSURLSession把这个txt下载,然后用这个库分页阅读。你可以选择不保存到本地,每次都让用户下载,或者保存到cache。也可以保存到本地自己管理
        hello_kity:@启发禅悟 我是在想那种在线阅读难道也是下载到本地吗?
        启发禅悟:@hello_kity 先把文件下载到本地就可啊。文本文件都不大的。
      • hello_kity:我最近也在做电子书阅读器~~学习了

      本文标题:iOS基于CoreText实现的电子书阅读器

      本文链接:https://www.haomeiwen.com/subject/spzeyttx.html