【问题标题】:UIImagePickerController presented from UIImageView inside UICollectionViewCellUIImagePickerController 从 UICollectionViewCell 内的 UIImageView 呈现
【发布时间】:2017-08-14 23:00:40
【问题描述】:

我在从 UIImageView 中的 UIImagePickerController 加载选定图像时遇到问题。 UIImageView 通过点击 collectionViewCell 中的按钮呈现。在 collectionViewCell 中点击该按钮时,UIImageView 会以动画形式显示在视图中。在点击该 UIImageView 时,会显示 uiimagepicker。选择图像时,选择器会很好地关闭,但图像不会在选择器关闭时加载到 uiimageView 内(占位符图像仍然存在并且不会被所选图像替换)。我的控制台中没有发生崩溃或错误。感谢您的帮助!

UICollectionViewCell 类 - LoginCell

class LoginCell: UICollectionViewCell, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

lazy var createUsernameButton: UIButton = {
    let customButton = UIButton(type: .system)
    customButton.setTitle("Create Username", for: .normal)
    customButton.addTarget(self, action: #selector(animateIn), for: .touchUpInside)
    return customButton
}()

func animateIn() {
    addSubview(profileImageView)

    profileImageView.transform = CGAffineTransform.init(scaleX: 1.3, y: 1.3)
    profileImageView.alpha = 0

    UIView.animate(withDuration: 0.2) {
        self.profileImageView.alpha = 1
        self.profileImageView.transform = CGAffineTransform.identity
    }

}

    lazy var profileImageView: UIImageView = {
        let imageView = UIImageView()
        imageView.image = UIImage(named: "avatar-bg-2x")
        imageView.addGestureRecognizer(UITapGestureRecognizer(target:self, action: #selector(handleSelectProfileImage)))
        imageView.isUserInteractionEnabled = true
        return imageView
    }()

    var loginController: LoginController?

    func handleSelectProfileImage() {
        guard let loginController = delegate as? LoginController else {
            return
        }
        loginController.showImagePicker()
    }

//.....
}

loginController

class LoginController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout, LoginControllerDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    weak var loginCollectionView: UICollectionView!
    var loginCell: LoginCell?

    func showImagePicker() {
        let picker = UIImagePickerController()
        picker.delegate = self
        picker.allowsEditing = true
        present(picker, animated: true, completion: nil)
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

        var selectedImageFromImagePicker: UIImage?

        if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage {
            selectedImageFromImagePicker = editedImage
        } else if let originalImage = info["UIImagePickerControllerOriginalImage"] as? UIImage {
            selectedImageFromImagePicker = originalImage
        }

        dismiss(animated: true, completion: {
            if let selectedImage = selectedImageFromImagePicker {
                self.loginCell?.profileImageView.image = selectedImage
                print("was dismissed")
            }
        })
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let loginCell = collectionView.dequeueReusableCell(withReuseIdentifier: loginCellId, for: indexPath) as! LoginCell
            loginCell.delegate = self
            return loginCell
    }
// ...
}

【问题讨论】:

  • 您确认selectedImageFromImagePicker 是正确的吗?看起来它的编码可能是nil
  • 我相信它没有返回 nil(一个值显示在控制台中,用于 selectedImageFromPicker)。当我使用它将选定的图像传递给标准 viewController 中的 UIImageView 时,同样的代码也可以正常工作。与这种情况的不同之处在于 profileImageView 呈现在 collectionViewCell(不是标准的 viewController)中。

标签: ios swift uiimageview uicollectionview uiimagepickercontroller


【解决方案1】:

我发现了问题,你没有在主线程上更新图像。试试这个:

1.更改登录控制器类中的代码以匹配以下代码。

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

    var selectedImageFromImagePicker: UIImage?

    if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage {
        selectedImageFromImagePicker = editedImage
    } else if let originalImage = info["UIImagePickerControllerOriginalImage"] as? UIImage {
        selectedImageFromImagePicker = originalImage
    }

    if let selectedImage = selectedImageFromImagePicker {
        DispatchQueue.main.async {
            self.loginCell?.profileImageView.image = selectedImage
            self.loginCollectionView.reloadData() //EDIT: add this new piece of code
        }
    }

    dismiss(animated: true, completion: nil)
}

var profileImage: UIImage?

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let loginCell = collectionView.dequeueReusableCell(withReuseIdentifier: loginCellId, for: indexPath) as! LoginCell
        loginCell.delegate = self
        loginCell.profileImageView.image = profileImage != nil ? profileImage : UIImage(named: "avatar-bg-2x")
        return loginCell
}

2.在您的 loginCell 类中更改此代码以匹配以下代码。

lazy var profileImageView: UIImageView = {
    let imageView = UIImageView()
    //removed line here
    imageView.addGestureRecognizer(UITapGestureRecognizer(target:self, action: #selector(handleSelectProfileImage)))
    imageView.isUserInteractionEnabled = true
    return imageView
}()

【讨论】:

  • 好的,谢谢。您的逻辑和主线程绝对有意义,但仍然无法正常工作。我更新了我的原始帖子,以显示可能缺少的内容,以便更清楚地了解我的结果。我想知道它是否与我的 UIImageView 的呈现方式有关......在我的情况下,我通过 animateIn() 函数将 UIImageView 呈现在 collectionViewCell 的顶部。不确定这是否会导致问题...?
  • 我实际上也考虑过更新...仍然无法正常工作,并且该更新得到“致命错误:在展开可选值时意外发现 nil”。
  • 您的逻辑完全合理并且越来越接近,但仍然无法正常工作并给出相同的致命错误.... hmmmmm ?
  • 我只是重新编写了将 UIImageView 呈现在新的 viewcontroller 类中而不是在 collectionViewCell 顶部的 uiview 中呈现的逻辑。这是目前完成我需要的工作。不过,感谢您的见解和时间!
猜你喜欢
  • 2016-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多