【iOS】screenshotServiceを使ってフルスクリーンショットを表示する方法

iOS 13からSafariなどでスクリーンショットを撮ると「フルページ」というタブでのフルスクリーンでのスクリーンショットが表示されるようになりました。

<img width="375" alt="IMG_E28A8A7F2693-1.jpeg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308861/47807ecd-c134-59e6-dfe7-996ed444df5b.jpeg">

しかしすべてのアプリがフルスクリーンショットを表示できるわけではなく、アプリ上での実装が必要になります。
今回はその実装についてまとめました。

# フルスクリーンショットを表示するために

フルスクリーンショットを表示するには、iOS 13から追加された[screenshotService](https://developer.apple.com/documentation/uikit/uiwindowscene/3213938-screenshotservice)を使用します。


screenshotServiceのdelegateの`screenshotService(_:generatePDFRepresentationWithCompletion:)`にフルスクリーンで表示する画面のpdf情報を渡すとフルスクリーンショットが表示されるようになります。

```swift

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のフルスクリーンショットの表示方法について実装してみます。

<img width="859" alt="スクリーンショット 2020-01-30 18.06.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308861/29cbfe71-22c9-d410-91a4-afbe8eccb09a.png">



``` swift

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))
    }
}

```
![Jan-30-2020 18-10-08.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308861/368cbb98-5496-e197-805d-485812808ea0.gif)


参考
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