iOS实现PDF文件浏览功能
程序员文章站
2023-08-17 22:48:07
写了一个小demo,显示本地pdf格式文件,支持翻页、跳页、缩放。
先看一下效果图:
ios开发,显示pdf格式文件方法有很多:
最简单的应该...
写了一个小demo,显示本地pdf格式文件,支持翻页、跳页、缩放。
先看一下效果图:
ios开发,显示pdf格式文件方法有很多:
- 最简单的应该是uiwebview,可以加载本地或网络pdf文件,支持上下滑动浏览、缩放。
- 优化一点的是用系统的qlpreviewcontroller加载,实现起来也比较方便,支持上下滑动浏览,左后滑动可多pdf文件切换,同时支持原生的分享打印,qlpreviewcontroller支持的文档格式也比较多,如pdf、doc、docx、xls、xlsx、txt、ppt、mp4...
- 上面两种都没有足够的自定义空间,不在这里做过多的介绍了,另外一种也就是本篇用到的ios核心图形库:core graphics,绘制pdf文档。
简单说一下逻辑,根据本地路径获取到cgpdfdocumentref,在drawrect中绘制上下文,画出pdf文件。通过uiscrollview实现缩放,添加uigesturerecognizer实现单击、双击、左滑、右滑功能。基于catransition实现翻页动画。
下面贴上核心代码:
承载pdf文件视图的控制器:hwpdfbrowsevc
#import <uikit/uikit.h> @interface hwpdfbrowsevc : uiviewcontroller @property (nonatomic, copy) nsstring *filepath; @property (nonatomic, copy) nsstring *filename; @end /*** ---------------分割线--------------- ***/ #import "hwpdfbrowsevc.h" #import "hwpdfbrowseview.h" #import "hwpdfbrowsetoolbar.h" #import "hwpdfbrowsescrollview.h" #define kpicmaxscale 3.0 #define kmainw [uiscreen mainscreen].bounds.size.width #define kmainh [uiscreen mainscreen].bounds.size.height @interface hwpdfbrowsevc ()<uiscrollviewdelegate, hwpdfbroesetoolbardelegate> @property (nonatomic, weak) hwpdfbrowsescrollview *scrollview; @property (nonatomic, weak) hwpdfbrowseview *browseview; @property (nonatomic, weak) hwpdfbrowsetoolbar *toolbar; @property (nonatomic, assign) cgfloat minzoomscale; @property (nonatomic, assign) cgfloat lastscrcontx; @end @implementation hwpdfbrowsevc - (void)viewdidload { [super viewdidload]; //初始化 self.view.backgroundcolor = [uicolor whitecolor]; self.navigationitem.title = _filename; //创建控件 [self creatcontrol]; } - (void)viewwilldisappear:(bool)animated { [super viewwilldisappear:animated]; //防止隐藏导航时,左滑返回导航消失 cgrect temnavbarframe = self.navigationcontroller.navigationbar.frame; temnavbarframe.origin.y = 20; self.navigationcontroller.navigationbar.frame = temnavbarframe; } - (void)creatcontrol { //导航右侧按钮 uibutton *deletebtn = [[uibutton alloc] initwithframe:cgrectmake(9, 0, 40, 40)]; deletebtn.titlelabel.font = [uifont systemfontofsize:16.f]; [deletebtn settitle:@"跳页" forstate:uicontrolstatenormal]; [deletebtn settitlecolor:[uicolor bluecolor] forstate:uicontrolstatenormal]; [deletebtn addtarget:self action:@selector(navbtnonclick) forcontrolevents:uicontroleventtouchupinside]; uiview *rightview = [[uiview alloc] initwithframe:cgrectmake(0, 0, 40, 40)]; [rightview addsubview:deletebtn]; self.navigationitem.rightbarbuttonitem = [[uibarbuttonitem alloc] initwithcustomview:rightview]; //scrollview hwpdfbrowsescrollview *scrollview = [[hwpdfbrowsescrollview alloc] initwithframe:[uiscreen mainscreen].bounds]; scrollview.delegate = self; scrollview.backgroundcolor = [uicolor blackcolor]; scrollview.maximumzoomscale = kpicmaxscale; scrollview.showsverticalscrollindicator = no; scrollview.showshorizontalscrollindicator = no; [self.view addsubview:scrollview]; _scrollview = scrollview; //pdf视图 hwpdfbrowseview *browseview = [[hwpdfbrowseview alloc] initwithfilepath:_filepath]; [scrollview addsubview:browseview]; _browseview = browseview; //绘制pdf视图后缩放至屏幕完全居中显示 cgrect frame = browseview.frame; frame.size.width = browseview.frame.size.width > kmainw ? kmainw : browseview.frame.size.width; frame.size.height = frame.size.width * (browseview.frame.size.height / browseview.frame.size.width); if (frame.size.height > kmainh) { frame.size.height = kmainh; frame.size.width = kmainh * (browseview.frame.size.width / browseview.frame.size.height); } //根据缩放调整 _minzoomscale = frame.size.width / browseview.frame.size.width; scrollview.allowscrollscale = _minzoomscale; scrollview.minimumzoomscale = _minzoomscale; scrollview.zoomscale = _minzoomscale; //底部工具栏 hwpdfbrowsetoolbar *toolbar = [[hwpdfbrowsetoolbar alloc] initwithframe:cgrectmake(0, kmainh - 49, kmainw, 49) currentpage:_browseview.currentpage totalpage:_browseview.totalpages]; toolbar.delegate = self; [self.view addsubview:toolbar]; _toolbar = toolbar; //单击 uitapgesturerecognizer *tap = [[uitapgesturerecognizer alloc] initwithtarget:self action:@selector(click)]; tap.numberoftouchesrequired = 1; tap.numberoftapsrequired = 1; [scrollview addgesturerecognizer:tap]; //双击 uitapgesturerecognizer *tapdouble = [[uitapgesturerecognizer alloc] initwithtarget:self action:@selector(doubleclick)]; tapdouble.numberoftapsrequired = 2; [scrollview addgesturerecognizer:tapdouble]; [tap requiregesturerecognizertofail:tapdouble]; //右滑手势 uiswipegesturerecognizer *rightswip = [[uiswipegesturerecognizer alloc] initwithtarget:self action:@selector(nextpage)]; rightswip.direction = uiswipegesturerecognizerdirectionleft; [scrollview addgesturerecognizer:rightswip]; //左滑手势 uiswipegesturerecognizer *leftswip = [[uiswipegesturerecognizer alloc] initwithtarget:self action:@selector(forwardpage)]; leftswip.direction = uiswipegesturerecognizerdirectionright; [scrollview addgesturerecognizer:leftswip]; } - (void)navbtnonclick { [_toolbar showwindow]; } //单击屏幕显示隐藏菜单 - (void)click { cgfloat navbary = _toolbar.frame.origin.y == kmainh - 49 ? -64 : 20; cgfloat toolbary = _toolbar.frame.origin.y == kmainh - 49 ? kmainh : kmainh - 49; [uiview animatewithduration:0.25 animations:^{ cgrect temnavbarframe = self.navigationcontroller.navigationbar.frame; temnavbarframe.origin.y = navbary; self.navigationcontroller.navigationbar.frame = temnavbarframe; cgrect temtoolbarframe = _toolbar.frame; temtoolbarframe.origin.y = toolbary; _toolbar.frame = temtoolbarframe; }]; } //双击屏幕放大缩小图片 - (void)doubleclick { [uiview animatewithduration:0.25f animations:^{ _scrollview.zoomscale = _scrollview.zoomscale == _minzoomscale ? kpicmaxscale : _minzoomscale; }]; } //左滑事件 - (void)nextpage { [_browseview nextpage]; _toolbar.currentpage = _browseview.currentpage; } //右滑事件 - (void)forwardpage { [_browseview prepage]; _toolbar.currentpage = _browseview.currentpage; } #pragma mark - uicousebrowsetoolbardelegate - (void)browsetoolbar:(hwpdfbrowsetoolbar *)browsetoolbar didclickfinishbuttonwithpage:(nsstring *)page { _browseview.currentpage = [page integervalue]; [_browseview reloadview]; [_toolbar dismisskeyboard]; _scrollview.zoomscale = _minzoomscale; } - (void)browsetoolbar:(hwpdfbrowsetoolbar *)browsetoolbar didpagebuttonwithaction:(bool)nextpage { if (nextpage) { [self nextpage]; }else { [self forwardpage]; } _scrollview.zoomscale = _minzoomscale; } #pragma mark - uiscrollviewdelegate - (void)scrollviewdidzoom:(uiscrollview *)scrollview { cgfloat offsetx = (scrollview.bounds.size.width > scrollview.contentsize.width) ? (scrollview.bounds.size.width - scrollview.contentsize.width) * 0.5 : 0.0; cgfloat offsety = (scrollview.bounds.size.height > scrollview.contentsize.height) ? (scrollview.bounds.size.height - scrollview.contentsize.height) * 0.5 : 0.0; _browseview.center = cgpointmake(scrollview.contentsize.width * 0.5 + offsetx, scrollview.contentsize.height * 0.5 + offsety - 64); } - (uiview *)viewforzoominginscrollview:(uiscrollview *)scrollview { return _browseview; } - (void)scrollviewdidscroll:(uiscrollview *)scrollview { if (scrollview.iszooming) return; //允许翻页的偏移量 cgfloat movepadding = 70.f; //仿苹果原生相册,图片放大后,滑动前在边界时在可以翻页,这里加了±10的偏移量 if (scrollview.contentoffset.x < - movepadding && _lastscrcontx < 10) { _scrollview.zoomscale = _minzoomscale; [self forwardpage]; } if (scrollview.contentsize.width - scrollview.contentoffset.x < kmainw - movepadding && scrollview.contentsize.width != 0 && fabsf(_lastscrcontx + kmainw - scrollview.contentsize.width) < 10) { _scrollview.zoomscale = _minzoomscale; [self nextpage]; } } //滑动自然停止时调用 - (void)scrollviewdidenddecelerating:(uiscrollview *)scrollview { _lastscrcontx = scrollview.contentoffset.x; } //滑动手动停止时调用 - (void)scrollviewdidenddragging:(uiscrollview *)scrollview willdecelerate:(bool)decelerate { _lastscrcontx = scrollview.contentoffset.x; } - (void)didreceivememorywarning { [super didreceivememorywarning]; // dispose of any resources that can be recreated. } @end
pdf文件视图:hwpdfbrowseview
#import <uikit/uikit.h> @interface hwpdfbrowseview : uiview{ cgpdfdocumentref pdfdocumentref; } @property (nonatomic, assign) nsinteger currentpage; @property (nonatomic, assign) nsinteger totalpages; - (id)initwithfilepath:(nsstring *)filepath; - (void)reloadview; - (void)prepage; - (void)nextpage; @end /*** ---------------分割线--------------- ***/ #import "hwpdfbrowseview.h" @implementation hwpdfbrowseview - (id)initwithfilepath:(nsstring *)filepath { pdfdocumentref = [self createpdffromexistfile:filepath]; self = [super initwithframe:cgpdfpagegetboxrect(cgpdfdocumentgetpage(pdfdocumentref, 1), kcgpdfmediabox)]; return self; } - (cgpdfdocumentref)createpdffromexistfile:(nsstring *)afilepath { cfstringref path = cfstringcreatewithcstring(null, [afilepath utf8string], kcfstringencodingutf8); cfurlref urlref = cfurlcreatewithfilesystempath(null, path, kcfurlposixpathstyle, no); cfrelease(path); cgpdfdocumentref document = cgpdfdocumentcreatewithurl(urlref); cfrelease(urlref); _totalpages = cgpdfdocumentgetnumberofpages(document); _currentpage = 1; if (_totalpages == 0) return null; return document; } - (void)reloadview { [self setneedsdisplay]; } - (void)drawrect:(cgrect)rect { cgcontextref context = uigraphicsgetcurrentcontext(); [[uicolor whitecolor] set]; cgcontextfillrect(context, rect); cgcontexttranslatectm(context, 0.0, rect.size.height); cgcontextscalectm(context, 1.0, -1.0); cgpdfpageref page = cgpdfdocumentgetpage(pdfdocumentref, _currentpage); cgaffinetransform pdftransform = cgpdfpagegetdrawingtransform(page, kcgpdfcropbox, rect, 0, true); cgcontextconcatctm(context, pdftransform); cgcontextdrawpdfpage(context, page); } //上一页 - (void)prepage { if(_currentpage < 2) { uialertview *alert = [[uialertview alloc]initwithtitle:@"提示" message:@"已经第一页了!" delegate:self cancelbuttontitle:@"确定" otherbuttontitles: nil ]; [alert show]; return; } --_currentpage; [self reloadview]; [self transitionwithtype:@"pageuncurl" withsubtype:kcatransitionfromright forview:self]; } //下一页 - (void)nextpage { if(_currentpage >= _totalpages) { uialertview *alert = [[uialertview alloc]initwithtitle:@"提示" message:@"已经最后一页了!" delegate:self cancelbuttontitle:@"确定" otherbuttontitles: nil ]; [alert show]; return; } ++_currentpage; [self reloadview]; [self transitionwithtype:@"pagecurl" withsubtype:kcatransitionfromright forview:self]; } //设置翻页动画效果 - (void)transitionwithtype:(nsstring *)type withsubtype:(nsstring *)subtype forview:(uiview *)view { catransition *animation = [catransition animation]; animation.duration = 0.7f; animation.type = type; if (subtype) animation.subtype = subtype; animation.timingfunction = uiviewanimationoptioncurveeaseinout; [view.layer addanimation:animation forkey:@"animation"]; } @end
demo 下载链接
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
上一篇: 豆腐鱼怎么吃,吃豆腐鱼会胖吗?