拍摄照片后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




