我有一个应用程序,可以显示用户在MKMapView上行走的位置。当用户离开地图视图时,应用程序将抓取屏幕并将图像保存在磁盘上。直到 iOSS 10.3,这种方法总是成功的。在iOS 11.0中,屏幕抓取是空白图像。我没有收到来自 xcode 的通知,说有一些更改,我需要调整代码。
有趣的是,文本页面中的屏幕抓取仍然被成功抓取和保存。
有没有人遇到同样的问题并得到了解决方案?
到目前为止,一直成功的代码是:
override func viewWillDisappear(_ animated: Bool) {
//Set the full file name under which the track will be saved.
let fileBaseName = self.imageName.appending(String(describing: (self.display?.trackDate)!))
let fileFullName = fileBaseName.appending(".png")
//Check if the image already has been saved
if !AuxiliaryObjects.shared.getImageFileName(with: fileFullName ) {
//Create the sizes of the capture
let screenRect = self.trackMapView.frame
let screenSize = screenRect.size
let screenScale = UIScreen.main.scale
var grabRect = self.trackMapView.convertRegion(self.mapRegion, toRectTo: self.view)
var heightAdjustment : CGFloat = 0.0
//Grab the image from the screen
UIGraphicsBeginImageContextWithOptions(screenSize, false, screenScale)
self.trackMapView.drawHierarchy(in: screenRect, afterScreenUpdates: true)
let myImage = UIGraphicsGetImageFromCurrentImageContext()
grabRect.origin.x *= (myImage?.scale)!
grabRect.origin.y *= (myImage?.scale)!
grabRect.size.width *= (myImage?.scale)!
grabRect.size.height *= (myImage?.scale)!
let grabImage = (myImage?.cgImage)!.cropping(to: grabRect)
let mapImage = UIImage(cgImage: grabImage!)
UIGraphicsEndImageContext()
AuxiliaryObjects.shared.save(image: mapImage, with: fileFullName, and: self.imageName)
self.display?.displayImage = AuxiliaryObjects.shared.getImage(with: fileFullName, with: self.tableImageRect)!
} else {
self.display?.displayImage = AuxiliaryObjects.shared.getImage(with: fileFullName, with: self.tableImageRect)!
}
}
我在Apple上提交了代码级支持请求,以获得问题的答案。苹果不支持使用drawHierarhy来抓取MapKit屏幕。要走的方法是使用 MKMapSnapshotter 实用程序创建 MKMapSnapshot,然后通过将所有地图坐标转换为查看坐标来绘制线条和注释。
由于这给我在获取镜像和正确转换坐标方面带来了一些问题,我决定使用图层方法render(in:CGContext),这为我提供了一个功能良好、非常有效的屏幕抓取。
func creatSnapshot(with fileName: String) {
UIGraphicsBeginImageContextWithOptions(self.trackMapView.frame.size, false, UIScreen.main.scale)
let currentContext = UIGraphicsGetCurrentContext()
self.trackMapView.layer.render(in: currentContext!)
let contextImage = (UIGraphicsGetImageFromCurrentImageContext())!
UIGraphicsEndImageContext()
let region = self.trackMapView.region
var cropRect = self.trackMapView.convertRegion(region, toRectTo: self.trackMapView.superview)
cropRect.origin.x *= contextImage.scale
cropRect.origin.y *= contextImage.scale
cropRect.size.height *= contextImage.scale
cropRect.size.width *= contextImage.scale
let cgMapImage = contextImage.cgImage?.cropping(to: cropRect)
let mapImage = UIImage(cgImage: cgMapImage!)
AuxiliaryObjects.shared.save(image: mapImage, with: fileName, and: self.imageName)
self.displayTrack?.displayImage = AuxiliaryObjects.shared.getImage(with: fileName, with: self.tableImageRect)!
NotificationCenter.default.post(name: self.imageSavedNotification, object: self)
}