UIImagePickerController 从 UICollectionViewCell 内的 UIImageView 呈现
Posted
技术标签:
【中文标题】UIImagePickerController 从 UICollectionViewCell 内的 UIImageView 呈现【英文标题】:UIImagePickerController presented from UIImageView inside UICollectionViewCell 【发布时间】: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)中。
【参考方案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 中呈现的逻辑。这是目前完成我需要的工作。不过,感谢您的见解和时间!以上是关于UIImagePickerController 从 UICollectionViewCell 内的 UIImageView 呈现的主要内容,如果未能解决你的问题,请参考以下文章
从 UITabBarController 驱动 UIImagePickerController
从 UIImagePickerController 保存视频
UIImagePickerController 从 UICollectionViewCell 内的 UIImageView 呈现
如何从 UIImagePickerController 获取图像文件名