iOS 13からSafariなどでスクリーンショットを撮ると「フルページ」というタブでのフルスクリーンでのスクリーンショットが表示されるようになりました。
しかしすべてのアプリがフルスクリーンショットを表示できるわけではなく、アプリ上での実装が必要になります。
今回はその実装についてまとめました。
フルスクリーンショットを表示するために
フルスクリーンショットを表示するには、iOS 13から追加されたscreenshotServiceを使用します。
screenshotServiceのdelegateのscreenshotService(_:generatePDFRepresentationWithCompletion:)
にフルスクリーンで表示する画面のpdf情報を渡すとフルスクリーンショットが表示されるようになります。
class ViewController1: UIViewController, UIScreenshotServiceDelegate {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
view.window?.windowScene?.screenshotService?.delegate = self
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
view.window?.windowScene?.screenshotService?.delegate = nil
}
func screenshotService(_ screenshotService: UIScreenshotService,
generatePDFRepresentationWithCompletion completionHandler: @escaping (Data?, Int, CGRect) -> Void) {
//completionHandlerにPDFデータ、現在のページindex、現在のページのrect
}
}
completionHandlerのパラメーターについて
completionHandlerにわたす(Data?, Int, CGRect)は以下のとおりです。
PDFData
フルスクリーンで表示するPDFデータ。
indexOfCurrentPage
PDFが複数ある時に表示したいページのindex。
複数ない場合は0を指定。
rectInCurrentPage
表示していたコンテンツの矩形領域。原点は左下になっている。
矩形領域が取得できない場合や常に上から表示したい場合はCGRectZeroを指定する。
実装サンプル
今回は以下のようなscreenと同じframeのscrollViewのフルスクリーンショットの表示方法について実装してみます。
import UIKit
class ViewController: UIViewController, UIScreenshotServiceDelegate {
@IBOutlet weak var scrollView: UIScrollView!
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
view.window?.windowScene?.screenshotService?.delegate = self
}
override func viewDidDisappear(_ animated: Bool) {
super.viewDidDisappear(animated)
view.window?.windowScene?.screenshotService?.delegate = nil
}
func screenshotService(_ screenshotService: UIScreenshotService,
generatePDFRepresentationWithCompletion completionHandler: @escaping (Data?, Int, CGRect) -> Void) {
// PDFデータの作成
let data = NSMutableData()
UIGraphicsBeginPDFContextToData(data, .zero, nil)
UIGraphicsBeginPDFPageWithInfo(.init(origin: .zero, size: scrollView.contentSize), nil)
if let context = UIGraphicsGetCurrentContext() {
let frame = scrollView.frame
let contentOffset = scrollView.contentOffset
let contentInset = scrollView.contentInset
scrollView.contentOffset = .zero
scrollView.contentInset = .zero
scrollView.frame = .init(origin: .zero, size: scrollView.contentSize)
scrollView.layer.render(in: context)
scrollView.frame = frame
scrollView.contentOffset = contentOffset
scrollView.contentInset = contentInset
}
UIGraphicsEndPDFContext()
let y = scrollView.contentSize.height - scrollView.contentOffset.y - scrollView.frame.height
completionHandler(data as Data, 0, .init(x: 0, y: y, width: view.frame.width, height: view.frame.height))
}
}
参考
https://developer.apple.com/documentation/uikit/uiwindowscene/3213938-screenshotservice
https://developer.apple.com/documentation/uikit/uiscreenshotservicedelegate/3213937-screenshotservice#declarations
https://github.com/sgr-ksmt/PDFGenerator