iOS长截图
背景
Twitter 上看到TaioApp的作者说,iOS 系统有支持长截图的API——UIScreenshotService,从 iOS 13开始就可以使用,下午的时候就在自己的 APP 中体验了一下。
过程
UIScreenshotService官方的说明如下:
When the user takes a screenshot of your app’s content, you work with a UIScreenshotService object to provide a PDF version of that screenshot. You do not create a UIScreenshotService object directly. Instead, you retrieve the object from the screenshotService property of your window scene and assign a delegate to it. When the user takes a screenshot, UIKit asks your delegate for the PDF data.
截屏时,使用UIScreenshotService 最终提供的是 PDF,需要通过UIScreenshotServiceDelegate
生成 PDF data.
使用如下:
把方法处理封装到单独的类,通过方法传入 view,来决定截屏时使用那个 view 来生成 PDF data。
.h文件
1 |
|
.m 文件
1 |
|
使用UIScreenshotService确实可以长截屏,截的内容的大小是ScrollView 的 contentSize。
但是有以下一些问题,需要注意:
不在 ScrollView 上的内容使用UIScreenshotService时看不到,比如 navigationBar、tabBar。
webview 的截屏,通过获取 webview 的 scrollview 的高度,也可以截到。但是,如果是 webview 里面加载的网页中间或者网页部分使用了滑动,即不是 WebView 的 Scroll而是 H5网页里的 Scroll,这样的显示,UIScreenshotService是获取不到的,因为最后不管怎么获取 webview 的 scrollview 的 contentSize 的Height一直都是那么高,滑动的部分不是这个 scrollview。
使用了
CAShapeLayer
之类的,生成圆角或者其他,如果没有设置 layer 的 fillColor,最终UIScreenshotService显示出来会是纯黑的。由于方法的回调依赖 scrollView 生成 PDF data,所以每个需要截图的界面,在进入时,都需要手动更新 contentScrollView,二级界面的还好说,可以hook scrollView 的初始化方法,保证每次创建时都更新 helper 的 contentScrollView,但是一级界面的几个 tab 切换,则只能通过手动更新的方式来设置(或者根据 tabIndex 获取不同的 scrollview),总之这也是需要注意的地方。
总结
UIScreenshotService确实能生成长截图,对于项目结构相对简洁明了、代码比较规范、只需要某个原生页面支持长截图的 APP 来说,可以使用。
但是如果项目中 H5多,且项目结构复杂的话,使用就不太方便了。