You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

拍摄照片后Segue未执行且APP崩溃,无日志报错问题求助

问题分析与解决方案

先理清楚你遇到的核心问题:拍照确认后执行Segue导致APP无声崩溃,Segue放在其他位置又会提前触发。我帮你拆解几个关键问题点和修复步骤:

1. 未关闭相机Picker就执行Segue(最可能的崩溃根源)

你在imagePickerController(_:didFinishPickingMediaWithInfo:)里直接调用performSegue,但此时相机的UIImagePickerController还处于被present的状态,直接Segue会导致导航控制器的栈逻辑混乱,这大概率是无报错崩溃的原因。

修复方法:先dismiss相机Picker,在dismiss的完成回调里再执行Segue,确保导航栈状态正常:

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    guard let pickedImage = info[UIImagePickerController.InfoKey.originalImage] as? UIImage else {
        picker.dismiss(animated: true, completion: nil)
        return
    }
    // 先关闭相机Picker,再在回调里执行Segue
    picker.dismiss(animated: true) { [weak self] in
        self?.performSegue(withIdentifier: "captured", sender: pickedImage)
    }
}

2. 移除冗余变量,简化传递逻辑

你的ViewController里声明了var img = UIImageView(),这个变量完全没必要——直接用选中的pickedImage作为Segue的sender传递即可,既简化代码又避免潜在的空值风险。

3. 替换强制解包,避免意外崩溃

prepare(for segue:)里你用了vc.imgAux = img.image!的强制解包,一旦图片获取异常就会触发崩溃。结合上面的修改,我们直接用sender传递的图片:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    guard segue.identifier == "captured",
          let targetVC = segue.destination as? ImageReportedVC,
          let selectedImage = sender as? UIImage else {
        return
    }
    targetVC.imgAux = selectedImage
}

4. 优化第二个VC的变量声明

ImageReportedVC里,你把imgAux初始化为空UIImage(),这没有意义,改成可选类型更符合逻辑:

class ImageReportedVC: UIViewController {
    var imgAux: UIImage? // 改为可选类型,避免默认空图片干扰
    @IBOutlet weak var imgReported: UIImageView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        imgReported.image = imgAux // 直接赋值,空值时imageView也会显示为空,逻辑合理
    }
}

额外排查点

如果修改后仍有问题,可以检查这些细节:

  • Storyboard里的Segue标识符captured是否拼写完全一致(大小写敏感)
  • 第二个VC的imgReportedIBOutlet是否正确连接,没有断连
  • 相机权限申请的回调是在后台线程,确保回到主线程执行UI操作(保险起见):
private func askPermision(){
    AVCaptureDevice.requestAccess(for: AVMediaType.video) {granted in
        DispatchQueue.main.async { 
            if granted {
                self.presentPicker()
            } else {
                print("Denied")
            }
        }
    }
}

按这些步骤修改后,应该能解决你的崩溃问题,同时代码也会更健壮。

内容的提问来源于stack exchange,提问作者Guillermo Fuentes

火山引擎 最新活动