本記事の趣旨
下記の目的に対して、巧妙な実装をしている解説記事が多かったので、よりシンプルな実装を提案するものです。
- 任意の
Viewのキャプチャ画像をUIImageとして取得する - 任意の
UIScrollView/UITableViewのコンテンツ全体の画像をUIImageとして取得する
万が一うまくいかなかったらコメントで教えていただけると幸いです。
方法
1. 任意の View のキャプチャ画像を UIImage として取得する
ここでは、UIView の extension として記述します。
UIView+getImage.swift
import UIKit
extension UIView {
func getImage() -> UIImage? {
// 確実に不透明なら、第2引数は true がよい
UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, 0.0)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
self.layer.render(in: context)
let capturedImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return capturedImage
}
}
2. 任意の UIScrollView / UITableView のコンテンツ全体の画像を UIImage として取得する
キャプチャの瞬間だけ、UIScrollView / UITableView の frame.size を contentSize に変更してしまう方針です。
UItableView は UIScrollView を継承しているので、UIScrollView の extension として記述します。
(先ほどの getImage() とconflict しないように別名のメソッド (getContentImage()) とします。)
UIScrollView+getContentImage.swift
import UIKit
extension UIScrollView {
func getContentImage() -> UIImage? {
UIGraphicsBeginImageContextWithOptions(captureSize, false, 0.0)
guard let context = UIGraphicsGetCurrentContext() else { return nil }
// 元の frame.size を記憶
let originalSize = self.frame.size
// frame.size を一時的に変更
self.frame.size = self.contentSize
self.layer.render(in: context)
// 元に戻す
self.frame.size = originalSize
let capturedImage: UIImage? = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext();
return capturedImage
}
}