前段时间有个需求:将滚动视图中的所有内容保存为图片。
写了一种通用的,检查contentSize没有问题之后运行保存,问题来了,无法将被遮住的部分也划分进图片区域,图片只有可见区域,反复检查区域宽高应该是没有问题的,iOS12可以全部保存为图片,iOS13以上的就不行。
百度UIScrollView生成图片,基本都和我写的一样,最后搜遮挡才搜到一个解决方案,废话不多说,上新鲜代码
extension UIScrollView {
func getImageOfScrollView() -> UIImage {
var image = UIImage()
UIGraphicsBeginImageContextWithOptions(self.contentSize, false, UIScreen.main.scale)
// save initial values
let savedContentOffset = self.contentOffset
let savedFrame = self.frame
let savedBackgroundColor = self.backgroundColor // reset offset to top left point
self.contentOffset = .zero
// set frame to content size
self.frame = CGRect(x: 0, y: 0, width: self.contentSize.width, height: self.contentSize.height)
// remove background
self.backgroundColor = UIColor.clear
// make temp view with scroll view content size
// a workaround for issue when image on ipad was drawn incorrectly
let tempView = UIView(frame: CGRect(x:0, y:0, width: self.contentSize.width, height:self.contentSize.height))
// save superview
let tempSuperView = self.superview // remove scrollView from old superview
self.removeFromSuperview()
// and add to tempView
tempView.addSubview(self)
// render view
// drawViewHierarchyInRect not working correctly
tempView.layer.render(in: UIGraphicsGetCurrentContext()!)
// and get image
image = UIGraphicsGetImageFromCurrentImageContext()!
// and return everything back
tempView.subviews[0].removeFromSuperview()
tempSuperView?.addSubview(self)
// restore saved settings
self.contentOffset = savedContentOffset
self.frame = savedFrame
self.backgroundColor = savedBackgroundColor
UIGraphicsEndImageContext()
return image
}
}
我原本写的如下
extension UIScrollView {
var screenshotImage: UIImage? {
var image: UIImage? = nil
UIGraphicsBeginImageContext(contentSize)
let formerContentOffset = contentOffset
let formerFrame = frame
self.contentOffset = .zero
self.frame = CGRect(origin: CGPoint.zero, size: contentSize)
UIGraphicsBeginImageContextWithOptions(contentSize, false, UIScreen.main.scale)
if let currentContext = UIGraphicsGetCurrentContext() {
self.layer.render(in: currentContext)
image = UIGraphicsGetImageFromCurrentImageContext()
}
UIGraphicsEndImageContext()
self.contentOffset = formerContentOffset
self.frame = formerFrame
return image
}
}
我有单独项目测试过原本写的版本,是没有问题的,也没找到具体原因,如有找到的请点评。
网友评论