我有一个带有View Controller A的UINavigationController。我将它推到View Controller B. View Controller B包含一个Image View,它通过以下代码异步加载它的图像:
let ss = MKMapSnapshotter(options: options)
ss!.start { (snapshot, error) in
guard let snappy = snapshot else {
return
}
let snap = snappy.image
...
// create a pinView which gets combined with the snapshot image
...
UIGraphicsBeginImageContextWithOptions(snap.size, false, snap.scale)
snap.draw(at: CGPoint(x: 0, y: 0))
let rect = CGRect(origin: CGPoint(x: self.frame.width/2 - pinView.frame.width/2, y: self.frame.height/2 - pinView.frame.height/2), size: CGSize(width: pinView.frame.width, height: pinView.frame.height))
pinView.drawHierarchy(in: rect, afterScreenUpdates: true)
let finalSnap = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
self.snapshotView.image = finalSnap
}
每当我按下VC B的后退按钮返回VC A时,如果图像尚未完成渲染,则弹出动画非常不稳定/迟缓/不稳定。我评论了一行,看看哪一行导致了迟缓,它发生在UIGraphicsGetImageFromCurrentImageContext
上(如果我按下< Back在该行被调用之前,则会出现此问题)
我尝试通过ss.cancel()
取消MKMapSnapshotter,我尝试在DispatchQueue.main.async{}
中包装UIGraphics上下文部分,我也尝试在viewWillDisappear
期间设置一个标记并检查isMovingFromParentViewController
告诉它不要运行该行,但由于图像创建是异步并立即启动,因此无法保证它已加载。他们都没有为我工作。
有没有人能够深入了解如何正确告诉我的VC B停止所有进程,或者我如何解决这个问题?如果我让快照图像完全加载,那么这个问题就不会发生,但我不能指望这种情况发生。
答案 0 :(得分:0)
根据@rmaddy的建议,我将图像创建移动到后台线程。我确实遇到了一个问题,但是drawHierarchy(in: rect, afterScreenUpdates: true)
无法在后台线程上调用,所以我改变了创建pinView的方式,这样我只需要通过我的当前图形上下文添加UIImage画在矩形。
最终代码的工作原理如下:
DispatchQueue.global(qos: .background).async {
UIGraphicsBeginImageContextWithOptions(snap.size, false, snap.scale)
snap.draw(at: CGPoint(x: 0, y: 0))
let rect = CGRect(origin: CGPoint(x: self.frame.width/2 - pinView.frame.width/2, y: self.frame.height/2 - pinView.frame.height/2), size: CGSize(width: pinView.frame.width, height: pinView.frame.height))
pinView.image?.draw(in: rect) // changed this to allow background thread execution
let finalSnap = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
// main thread image view assignment
DispatchQueue.main.async {
self.snapshotView.image = finalSnap
}
}