You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中UIImagePickerController拍照后无法显示预览的问题

相机拍照后图片无法显示在UIImageView的问题排查与解决

问题场景

Swift开发中,界面包含两个图片控件profilePicImage和rightProfilePicImg,通过ImageChooser枚举标记用户点击的按钮。当前实现下,从相册选择图片可正常显示到对应控件,但调用相机拍照后,图片无法显示在控件内(不过图片值能正常传入JSON参数)。

相关代码

enum ImageChooser {case profile,right}

let imagePickerEdit = UIImagePickerController()
var chooser:ImageChooser = .profile


@IBAction func profilePicBtn(_ sender: UIButton) {
    chooser = .profile
}
@IBAction func rightProfileBtn(_ sender: UIButton) {
    chooser = .right
 let alert = UIAlertController(title: "Choose Image", message: nil, preferredStyle: .actionSheet)
           alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: { _ in
               self.openCamera()
           }))

           alert.addAction(UIAlertAction(title: "Gallery", style: .default, handler: { _ in
               self.openGallery()
           }))

           alert.addAction(UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil))

           self.present(alert, animated: true, completion: nil)

}

@IBAction func profilePicBtn(_ sender: UIButton) {
    chooser = .profile
    
    let alert = UIAlertController(title: "Choose Image", message: nil, preferredStyle: .actionSheet)
           alert.addAction(UIAlertAction(title: "Camera", style: .default, handler: { _ in
               self.openCamera()
           }))

           alert.addAction(UIAlertAction(title: "Gallery", style: .default, handler: { _ in
               self.openGallery()
           }))

           alert.addAction(UIAlertAction.init(title: "Cancel", style: .cancel, handler: nil))

           self.present(alert, animated: true, completion: nil)
    
}

 func openCamera()
{
    if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.camera) {
        imagePickerEdit.delegate = self
        imagePickerEdit.sourceType = UIImagePickerController.SourceType.camera
        imagePickerEdit.allowsEditing = false
        self.present(imagePickerEdit, animated: true, completion: nil)
    }
    else
    {
        let alert  = UIAlertController(title: "Warning", message: "You don't have camera", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }
}

func openGallery()
{
    if UIImagePickerController.isSourceTypeAvailable(UIImagePickerController.SourceType.photoLibrary){
       // let imagePicker = UIImagePickerController()
        imagePickerEdit.delegate = self
        imagePickerEdit.allowsEditing = true
        imagePickerEdit.sourceType = UIImagePickerController.SourceType.photoLibrary
        self.present(imagePickerEdit, animated: true, completion: nil)
    }
    else
    {
        let alert  = UIAlertController(title: "Warning", message: "You don't have permission to access gallery.", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }
}

extension NewEditProfileViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    if let pickedImage = info[.originalImage] as? UIImage {
                    if chooser == .profile {
                        profilePicImage.image = pickedImage
                    }
                     if chooser == .right {
                        rightProfilePicImg.image = pickedImage
                    }
                }
    picker.dismiss(animated: true, completion: nil)
}
}

问题原因分析

  1. 重复的IBAction方法:存在两个同名的profilePicBtn IBAction,会导致按钮关联异常,编译时出现警告,可能造成逻辑执行混乱。
  2. UI更新未确保在主线程:相机拍照后的回调可能在非主线程执行,直接更新UIImageView的image属性会导致UI无法刷新(相册选择的回调通常在主线程,所以能正常显示)。
  3. 全局UIImagePickerController复用的潜在问题:全局复用imagePickerEdit时,每次打开相机/相册未完全重置配置,可能导致参数冲突。

解决步骤

1. 删除重复的IBAction方法

保留包含弹窗逻辑的profilePicBtn方法,删除仅设置chooser的同名方法,确保按钮点击能正确弹出选择菜单并设置对应的chooser值。

2. 确保UI更新在主线程执行

在代理方法中更新UIImageView时,强制切换到主线程:

extension NewEditProfileViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
    picker.dismiss(animated: true) {
        // 确保在主线程更新UI
        DispatchQueue.main.async {
            if let pickedImage = info[.originalImage] as? UIImage {
                if self.chooser == .profile {
                    self.profilePicImage.image = pickedImage
                } else if self.chooser == .right {
                    self.rightProfilePicImg.image = pickedImage
                }
            }
        }
    }
}
}

3. 优化UIImagePickerController的使用

避免全局复用,改为每次打开相机/相册时创建新的实例,防止配置冲突:

// 删除全局的imagePickerEdit,改为在方法内创建
func openCamera() {
    if UIImagePickerController.isSourceTypeAvailable(.camera) {
        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.sourceType = .camera
        imagePicker.allowsEditing = false
        self.present(imagePicker, animated: true)
    } else {
        let alert = UIAlertController(title: "Warning", message: "You don't have camera", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        self.present(alert, animated: true)
    }
}

func openGallery() {
    if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {
        let imagePicker = UIImagePickerController()
        imagePicker.delegate = self
        imagePicker.allowsEditing = true
        imagePicker.sourceType = .photoLibrary
        self.present(imagePicker, animated: true)
    } else {
        let alert = UIAlertController(title: "Warning", message: "You don't have permission to access gallery.", preferredStyle: .alert)
        alert.addAction(UIAlertAction(title: "OK", style: .default))
        self.present(alert, animated: true)
    }
}

4. 统一判断逻辑

将代理方法中的两个if改为else if,避免不必要的判断执行,提升代码效率。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 15:50:37