从相册选取图片时NavigationController出现异常问题
Hey there! Let's figure out why you're getting sent back to the first ViewController after picking an image from the photo library. This is a common gotcha for Swift beginners, so don't worry—we'll fix it together.
最可能的原因及解决方案
1. 错误的图片选择器present方式
这是最常见的问题:如果你不是通过当前的第二个ViewController来present图片选择器,而是用了根控制器或者全局窗口的present方法,就会导致dismiss后回到导航栈的根VC(第一个ViewController)。
正确的做法:在第二个ViewController的按钮点击事件里,直接用self来present选择器:
@IBAction func pickImageButtonTapped(_ sender: UIButton) { let imagePicker = UIImagePickerController() imagePicker.delegate = self imagePicker.sourceType = .photoLibrary // 关键:用当前VC present,而不是根控制器 self.present(imagePicker, animated: true, completion: nil) }
2. 误操作导航栈的dismiss逻辑
在图片选择完成的代理方法里,要确保你只是dismiss图片选择器,而不是调用popViewController(那会直接回到第一个VC)。
正确的代理实现:
extension SecondViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate { func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) { // 取出选中的图片并显示 if let selectedImage = info[.originalImage] as? UIImage { yourImageView.image = selectedImage } // 只dismiss图片选择器,不要碰导航栈 picker.dismiss(animated: true, completion: nil) } func imagePickerControllerDidCancel(_ picker: UIImagePickerController) { // 取消时同样只dismiss选择器 picker.dismiss(animated: true, completion: nil) } }
3. 确认跳转第二个VC的方式正确
确保你从第一个ViewController跳转到第二个是用push方式(符合NavigationController的栈结构),而不是present:
// 第一个ViewController的按钮点击事件 @IBAction func goToSecondVCTapped(_ sender: UIButton) { let secondVC = SecondViewController() // 或者从storyboard初始化 self.navigationController?.pushViewController(secondVC, animated: true) }
4. 排查导航栈是否被意外修改
如果上面的步骤都没问题,可以在第二个ViewController的viewDidAppear里打印导航栈状态,看看选图回来后栈里的VC是否还存在:
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) guard let navController = navigationController else { return } print("当前导航栈VC数量:\(navController.viewControllers.count)") print("导航栈中的VC:\(navController.viewControllers.map { String(describing: $0) })") }
如果选图回来后数量变成1,说明有其他地方(比如AppDelegate或SceneDelegate的生命周期方法)修改了导航栈或根控制器,需要排查这些代码。
内容的提问来源于stack exchange,提问作者Encoders

