我正在尝试从用户手机中选择图像并使用所述图像更新图像视图。
我遇到的问题是它不会更新图像。它确实到达那里,因为我添加了断点并且它到达了断点,并且图像视图可以在我手动尝试将其更改为其他地方时更改图像。
但是当我需要它时它拒绝工作。
我的图片视图:
lazy var profilePictureImageView: UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "DefaultUser")
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFill
imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleSelectProfilePicture)))
imageView.isUserInteractionEnabled = true
return imageView
}()
通过在设备上挑选照片来更新图像的代码:
import UIKit
extension ProfileVC: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func handleSelectProfilePicture() {
let picker = UIImagePickerController()
picker.delegate = self
picker.allowsEditing = true
present(picker, animated: true, completion: nil)
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var selectedImageFromPicker: UIImage?
if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage {
selectedImageFromPicker = editedImage
}
else if let originalImage = info["UIImagePickerControllerOriginalImage"] as? UIImage {
selectedImageFromPicker = originalImage
}
if let selectedImage = selectedImageFromPicker {
profilePictureImageView.image = selectedImage
}
dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
}
[编辑]我发现的一件事是,如果我在具有不同图像视图的不同VC上尝试它,它可以按预期工作。我可以在两个VC之间看到的唯一主要区别是我希望它能够工作但不会扩展'UIPickerViewDelegate'和'UIPickerViewDataSource'。可能会发生冲突吗?
答案 0 :(得分:8)
试试这个,它对我有用:
DispatchQueue.main.async {
profilePictureImageView.image = croppedImage
profilePictureImageView.setNeedsDisplay()
}
基本上,您需要指定要通过
更新图像profilePictureImageView.setNeedsDisplay()
答案 1 :(得分:2)
您希望在主线程上进行所有UI更新 - 例如更改图像:
if let selectedImage = selectedImageFromPicker {
DispatchQueue.main.async {
profilePictureImageView.image = selectedImage
}
}
应该这样做。
答案 2 :(得分:1)
我对此代码没有任何问题,我试图尽可能地复制您的代码。
class ViewController: UIViewController {
lazy var imageView: UIImageView = {
let iView = UIImageView()
iView.contentMode = .scaleAspectFill
iView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleSelectProfilePicture)))
iView.isUserInteractionEnabled = true
return iView
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(imageView)
self.imageView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint(item: imageView, attribute: .height, relatedBy: .equal, toItem: self.view, attribute: .height, multiplier: 1.0, constant: 1.0).isActive = true
NSLayoutConstraint(item: imageView, attribute: .width, relatedBy: .equal, toItem: self.view, attribute: .width, multiplier: 1.0, constant: 1.0).isActive = true
}
func handleSelectProfilePicture() {
let picker = UIImagePickerController()
picker.delegate = self
picker.allowsEditing = true
present(picker, animated: true, completion: nil)
}
}
extension ViewController: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
var selectedImageFromPicker: UIImage?
if let editedImage = info["UIImagePickerControllerEditedImage"] as? UIImage {
selectedImageFromPicker = editedImage
}
else if let originalImage = info["UIImagePickerControllerOriginalImage"] as? UIImage {
selectedImageFromPicker = originalImage
}
if let selectedImage = selectedImageFromPicker {
imageView.image = selectedImage
}
dismiss(animated: true, completion: nil)
}
func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
dismiss(animated: true, completion: nil)
}
}
问题必须由代码中的其他内容引起。我和你一样使用了懒惰的var。您是否可以尝试将代码简化为此代码并查看其是否有效或发布其余代码。你设定了什么限制?
答案 3 :(得分:0)
尝试将modalPresentationStyle设置为overCurrentContext 像下面的示例
let myPickerController = UIImagePickerController()
myPickerController.delegate = self
myPickerController.sourceType = UIImagePickerControllerSourceType.photoLibrary
**myPickerController.modalPresentationStyle = .overCurrentContext**
myPickerController.delegate = self
present(myPickerController, animated: true, completion: nil)
答案 4 :(得分:0)
这是另一种可能对某人有用的情况:
我有同样的问题,除了我的ImageView在TableViewCell上。
工作已在主线程上完成。
调用imageView.setNeedsDisplay()
甚至在每个超级视图上都无济于事。
出于某种奇怪的原因,仅在包含imageView的单元格上调用setNeedsLayout()
才有帮助。
我检查了布局,在此调用之前和之后,所有视图的顺序和位置都相同。
我不确定为什么这样做有效,因此我一无所知,因此,如果有人有任何想法,将不胜感激。
答案 5 :(得分:0)
我现在尝试并成功的方法是进入UITabBarController
,并在viewControllers
内而不是原来的viewDidLoad()
内创建所有viewWillAppear()
。 / p>
一个便笺,您必须使用dispatch
进行操作,否则该应用将崩溃
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async {
self.setupViewControllers()
}
}
好像是因为viewController是在viewWillAppear()
内创建的,因此uiPicker
关闭时,viewControllers
将再次加载,并且所选图像将丢失。
答案 6 :(得分:0)
首先使用
将现有图像值设置为空 imageView.image = nil
然后将新图像添加到图像视图
let yourImage = UIImage(named: "your_image_name")
imageView.image = yourImage
这对我有用