当使用各种UIView
扩展来拍摄UIView
的快照时,结果可能看起来比它应该更大(放大的类型)。
我拍摄了2张UIViews
的快照,我们可以在下面的内容中调用viewS和viewS。
UIView
以供显示。我已经测试了3个不同的代码来获得我正在寻找的结果:一个提供了所需的快照图像,但渲染质量低;另外两个为viewA提供了更好质量的图像渲染和正确的结果,但对于viewB,虽然快照似乎有正确的矩形(我检查了rects),但是显示的图像看起来太大(好像它们被放大了两次)。
extension UIView {
func takeSnapshot() -> UIImage? {
UIGraphicsBeginImageContext(self.frame.size)
self.layer.render(in: UIGraphicsGetCurrentContext()!)
let snapshot = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return snapshot
}
}
extension UIView {
func snapshot(of rect: CGRect? = nil, afterScreenUpdates: Bool = true) -> UIImage {
return UIGraphicsImageRenderer(bounds: rect ?? bounds).image { _ in
drawHierarchy(in: bounds, afterScreenUpdates: true)
}
}
}
extension UIView {
func takeScreenshot() -> UIImage {
UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, UIScreen.main.scale)
drawHierarchy(in: self.bounds, afterScreenUpdates: true)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
if (image != nil) { return image! }
return UIImage()
}
}
最后但并非最不重要的是,用于从快照中提取裁剪图像的(简化)代码
for i in (0...numberOfCroppedImages) {
let rect = CGRect(x: CGFloat(i) * snapshot!.size.width / CGFloat(numberOfCroppedImages), y: 0, width: snapshot!.size.width / CGFloat(numberOfCroppedImages), height:snapshot!.size.height)
// defines the container view for the fragmented snapshots
let view = UIView()
view.frame = rect
// defines the layer with the fragment of the snapshot
let layer = CALayer()
layer.frame.size = rect.size
let img = snapshot?.cgImage?.cropping(to: rect)
layer.contents = img
view.layer.addSublayer(layer)
}
我已经加倍检查了所有的CGRect
并且我没有发现它们的任何问题:视图矩形以及快照大小似乎是预期的那个,但是,我一直有太大的渲染图像,扩展名为#2&#3对于viewB(viewA被正确渲染),而扩展#1给出了正确尺寸的图像,但质量太低而无法充分使用。
这可能是drawInHierarchy(in: afterScreenUpdates:)
的问题吗?或者用let img = snapshot?.cgImage?.cropping(to: rect)
转换为cgImage?
我会非常感谢任何指针!
我发布了一个我发现适合我的解决方案:
首先,一个快照扩展,为(无论是质量还是尺寸)呈现(无论是质量还是大小)视图是否添加到层次结构中,是否裁剪,以及:
extension UIView {
func takeSnapshot(of rect: CGRect? = nil, afterScreenUpdates: Bool = true) -> UIImage {
return UIGraphicsImageRenderer(bounds: rect ?? bounds).image { (context) in
self.layer.render(in: context.cgContext)
}
}
}
然后是在视图中获取rect快照的代码的更新版本:
let view = UIView()
view.frame = rect
let img = self.takeSnapshot(of: rect, afterScreenUpdates: true).cgImage
view.layer.contents = img
这里的区别在于在视图中拍摄矩形的快照,而不是裁剪整个视图的快照。
我希望这有帮助。