【问题标题】:UIImage from UIView image capture keeps crashing? Swift iOS9UIView 图像捕获中的 UIImage 不断崩溃?斯威夫特iOS9
【发布时间】:2017-01-19 08:07:28
【问题描述】:

这是一个奇怪的问题,因为有时代码可以正常工作,而有时它会崩溃。但最近它只是崩溃了。

我有一个从 uiview 获取的图像。我使用下面的捕获功能抓取图像,然后将图像发送到属性以转到 prepareForSegue 以发送到下一个视图控制器。返回图像时,代码会不断崩溃。我对其进行了调试,发现该属性肯定从 nil 变为包含图像,但是当它需要 segue 时它崩溃了。但是崩溃是在捕获功能中而不是在segue中。这很奇怪,因为图像被返回(调试器显示它)但捕获返回是崩溃不断发生的地方。崩溃发生在:

//This seems to be the main problem
return capturedImage

这是返回的 captureImage 的崩溃日志

Thread1: EXC_BAD_INSTRUCTION (code=EXC_1336_INVOP, subcode=0x0)

我在这条线上也遇到了崩溃,但不知何故崩溃停止了。我无法为这个添加崩溃日志,因为它停止了崩溃,但我不知道它为什么或如何停止

view!.layer.renderInContext(UIGraphicsGetCurrentContext()!)

有什么想法吗?

顺便说一句,我使用情节提要按钮来触发转场。

class MainController: UIViewController {

@IBOutlet weak var mainView: UIView!

var mainPic: UIImage? 


override func viewDidLoad() {
        super.viewDidLoad()
}

//MARK: -Func to convert image in uiview to uiimage
//get image from UIView, render it for Retina compatibility, then return it as an UIImage
func captureAndRenderUIImageFromUIView(view:UIView?) -> UIImage {

    UIGraphicsBeginImageContextWithOptions((view?.bounds.size)!, true, 0.0)
    view!.drawViewHierarchyInRect(view!.bounds, afterScreenUpdates: true)

    //I was also getting crashes on this line but they stopped??
    view!.layer.renderInContext(UIGraphicsGetCurrentContext()!)
    let capuredImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    //The return value is where the crash keeps happening
    return capturedImage
}

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

     self.mainPic = self.captureAndRenderUIImageFromUIView(mainView)

     if segue.identifier == "toDetailController"{

     let detailVC = segue.destinationViewController as! DetailController
     detailVC.detailPic = self.mainPic!
    }
 }

}

}

这是它要去的视图

class DetailController: UIViewController {
@IBOutlet weak var imageView: UIImageView!

var detailPic: UIImage? 

override func viewDidLoad() {
     super.viewDidLoad()
     self.imageView.image = self.detailPic
   }

}

【问题讨论】:

  • 不要继续猜测。有什么错误?使用崩溃的准确和完整详细信息更新您的问题。
  • @maddy 哦,对了,我马上更新
  • @maddy 更新了,谢谢
  • 错误应该更多。你能在调试器中重现崩溃吗?
  • 我刚试过。当调试器到达崩溃线时,唯一显示的是我更新的崩溃线。调试器本身是空白的。

标签: ios swift uiview uiimage


【解决方案1】:

您好:我开始尝试以与您在这里尝试的方式大致相同的方式做事;但是,它容易出错且不稳定。我最近发现使用 UIView 方法 snapshotViewAfterScreenUpdates 可以省去很多麻烦。只需在要拍摄快照的视图上直接调用它,它就会返回一个 UIImage。

您可以在以下位置查看更多详细信息: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/#//apple_ref/occ/instm/UIView/snapshotViewAfterScreenUpdates:

事实上,我在这里也学到了一些东西,因为似乎有一系列这些函数(例如,一个为您提供可调整大小的 UIImageView 的函数)。

希望对您有所帮助。

编辑:在我的一个应用程序中,我通过如下子程序实现了这一点:

func getSnapshot(target: UIView) -> Void {
            // Clean down
            if let _ = self.snapshotView where self.snapshotView.isDescendantOfView(self) {
                self.snapshotView.removeFromSuperview()
            }

            self.snapshotView = target.snapshotViewAfterScreenUpdates(true)
            let snapshotFrame : CGRect = CGRect(origin: recognizer.locationInView(self), size: target.frame.size)
            self.snapshotView.frame = snapshotFrame
            self.addSubview(self.snapshotView)

            self.canMoveSnapshot = true
        }

【讨论】:

  • 感谢您的帮助,我现在正在查看文档。你为什么说代码容易出错?你发现了什么问题?
  • 简短的回答是它运行得不太好(!)。但是,我认为当您使用大量视图时,尝试隔离要捕获的屏幕部分以获得正确的 CGContext 可能会很耗时并且容易出错。我建议的函数在一个方法调用中为您处理所有这些。
  • 我在您发送的文档链接上查找了该方法,它似乎返回了一个视图对象。你是如何让它从一个视图对象变成一个图像对象的? func snapshotViewAfterScreenUpdates(_ afterUpdates: Bool) -> UIView
  • 你能上传你用来管理它的代码吗?我读到这篇文章说你应该使用'drawViewHierarchyInRec'。 stackoverflow.com/questions/20203682/…
  • 对造成的混乱表示歉意。该方法确实返回 UIView 而不是 UIImageView。但是,UIView 的内容包含您要求提供快照的视图的渲染图像。我在上面的原始答案中添加了我的代码。您可以使用 drawViewHierarchyInRect 完成您想要的,但我认为如果可能的话,您应该尝试使用 snapshotAfterScreenUpdates,因为它是更“当前”的方法。
猜你喜欢
  • 2017-04-24
  • 2018-11-02
  • 1970-01-01
  • 1970-01-01
  • 2015-08-19
  • 1970-01-01
  • 2017-07-22
  • 2017-03-24
  • 1970-01-01
相关资源
最近更新 更多