ImageView 不会更新新图像
ImageView won't update with new image
我正在尝试 select 来自用户 phone 的图像并使用该图像更新图像视图。
我遇到的问题是它不会更新图像。当我添加一个断点并且它到达断点时它确实到达了那里,并且当我手动尝试在其他地方更改它时图像视图可以更改图像。
但是当我需要它时它拒绝工作。
我的图片浏览:
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' 的那个。会不会有冲突?
您想在主线程上进行所有 UI 更新——例如更改图像:
if let selectedImage = selectedImageFromPicker {
DispatchQueue.main.async {
profilePictureImageView.image = selectedImage
}
}
应该做。
我对这段代码没有任何问题,我已尝试尽可能多地复制您的代码。
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)
}
}
问题一定是由您的代码中的其他内容引起的。我使用了一个和你一样的惰性变量。您能否尝试将您的代码简化为这个并查看它是否有效或 post 其余代码。您设置了哪些限制条件?
试试这个,它对我有用:
DispatchQueue.main.async {
profilePictureImageView.image = croppedImage
profilePictureImageView.setNeedsDisplay()
}
基本上你需要指定你想通过
更新图像
profilePictureImageView.setNeedsDisplay()
尝试将 modalPresentationStyle 设置为 overCurrentContext
喜欢下面的示例
let myPickerController = UIImagePickerController()
myPickerController.delegate = self
myPickerController.sourceType = UIImagePickerControllerSourceType.photoLibrary
**myPickerController.modalPresentationStyle = .overCurrentContext**
myPickerController.delegate = self
present(myPickerController, animated: true, completion: nil)
这是另一个可能对某人有用的案例:
我遇到了同样的问题,只是我的 ImageView 在 TableViewCell 上。
工作在主线程上完成。
没有任何工作包括调用 imageView.setNeedsDisplay()
甚至在每个超级视图上。
出于某种奇怪的原因,有帮助的只是在包含 imageView 的 cell 上调用 setNeedsLayout()
。
我检查了布局,在此调用之前和之后所有视图的顺序和位置都相同。
我不确定为什么会这样,除此之外什么都没有,所以如果有人有任何想法,我们将不胜感激。
我现在自己尝试的方法是进入 UITabBarController
,并在 viewDidLoad()
中创建所有 viewControllers
,而不是在最初所在的 viewWillAppear()
中.
请注意,您必须使用 dispatch
否则应用程序会崩溃
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async {
self.setupViewControllers()
}
}
看起来是因为 viewController 是在 viewWillAppear()
中创建的,在 uiPicker
关闭后 viewControllers
将再次加载并且所选图像将丢失。
首先使用
将现有图像值设为空
imageView.image = nil
然后将新图像添加到图像视图
let yourImage = UIImage(named: "your_image_name")
imageView.image = yourImage
这对我有用
我正在尝试 select 来自用户 phone 的图像并使用该图像更新图像视图。
我遇到的问题是它不会更新图像。当我添加一个断点并且它到达断点时它确实到达了那里,并且当我手动尝试在其他地方更改它时图像视图可以更改图像。
但是当我需要它时它拒绝工作。
我的图片浏览:
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' 的那个。会不会有冲突?
您想在主线程上进行所有 UI 更新——例如更改图像:
if let selectedImage = selectedImageFromPicker {
DispatchQueue.main.async {
profilePictureImageView.image = selectedImage
}
}
应该做。
我对这段代码没有任何问题,我已尝试尽可能多地复制您的代码。
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)
}
}
问题一定是由您的代码中的其他内容引起的。我使用了一个和你一样的惰性变量。您能否尝试将您的代码简化为这个并查看它是否有效或 post 其余代码。您设置了哪些限制条件?
试试这个,它对我有用:
DispatchQueue.main.async {
profilePictureImageView.image = croppedImage
profilePictureImageView.setNeedsDisplay()
}
基本上你需要指定你想通过
更新图像profilePictureImageView.setNeedsDisplay()
尝试将 modalPresentationStyle 设置为 overCurrentContext 喜欢下面的示例
let myPickerController = UIImagePickerController()
myPickerController.delegate = self
myPickerController.sourceType = UIImagePickerControllerSourceType.photoLibrary
**myPickerController.modalPresentationStyle = .overCurrentContext**
myPickerController.delegate = self
present(myPickerController, animated: true, completion: nil)
这是另一个可能对某人有用的案例:
我遇到了同样的问题,只是我的 ImageView 在 TableViewCell 上。
工作在主线程上完成。
没有任何工作包括调用 imageView.setNeedsDisplay()
甚至在每个超级视图上。
出于某种奇怪的原因,有帮助的只是在包含 imageView 的 cell 上调用 setNeedsLayout()
。
我检查了布局,在此调用之前和之后所有视图的顺序和位置都相同。
我不确定为什么会这样,除此之外什么都没有,所以如果有人有任何想法,我们将不胜感激。
我现在自己尝试的方法是进入 UITabBarController
,并在 viewDidLoad()
中创建所有 viewControllers
,而不是在最初所在的 viewWillAppear()
中.
请注意,您必须使用 dispatch
否则应用程序会崩溃
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async {
self.setupViewControllers()
}
}
看起来是因为 viewController 是在 viewWillAppear()
中创建的,在 uiPicker
关闭后 viewControllers
将再次加载并且所选图像将丢失。
首先使用
将现有图像值设为空 imageView.image = nil
然后将新图像添加到图像视图
let yourImage = UIImage(named: "your_image_name")
imageView.image = yourImage
这对我有用