为啥我的图像没有出现在 UIImage 视图中?

Posted

技术标签:

【中文标题】为啥我的图像没有出现在 UIImage 视图中?【英文标题】:why my Image doesn't appear in UIImage View?为什么我的图像没有出现在 UIImage 视图中? 【发布时间】:2018-02-13 02:33:22 【问题描述】:

我做了一个视图控制器来显示一个图像,图像将在用户按下checkOutVC 中的右键项目后显示,就像这样

图片应该像这样出现在ReusableImageDisplayVC

我将图像从checkOutVC 发送到ReusableImageDisplayVC,我用于这些视图控制器的代码如下:

class CheckoutTVC: UITableViewController 

 @IBAction func openImageBarButtonDidPressed(_ sender: Any) 

        var displayedImage = UIImage()
        let imagePath = "https://***.jpg"
        let urlImage = URL(string: imagePath)

        NetworkingService.fetchData(url: urlImage!)  (result) in
            self.activityIndicator.startAnimating()

            switch result 
            case .failure(let error) :
                self.activityIndicator.stopAnimating()
                self.showAlert(alertTitle: "Sorry", alertMessage: error.localizedDescription, actionTitle: "Back")
            case .success (let imageData):
                self.activityIndicator.stopAnimating()
                displayedImage = UIImage(data: imageData)!
            
        


        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let popup = storyboard.instantiateViewController(withIdentifier: "imageDisplay") as! ReusableImageDisplayVC
        popup.photo = displayedImage


        present(popup, animated: true, completion: nil)

    

ReusableImageDisplayVC 中的代码如下

class ReusableImageDisplayVC: UIViewController 

    @IBOutlet weak var ImagePhoto: UIImageView!
    var photo : UIImage?

    override func viewDidLoad() 
        super.viewDidLoad()

        if photo == nil 
            print("photo is nil")
         else 
            print("photo is not nil")
        

        print(photo!)

        ImagePhoto.image = photo!


        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ReusableImageDisplayVC.tapFunction(sender:)))
        tapGesture.numberOfTapsRequired = 1
        ImagePhoto.addGestureRecognizer(tapGesture)
        view.addGestureRecognizer(tapGesture)

    



    @objc func tapFunction(sender: UITapGestureRecognizer) 
        dismiss(animated: true, completion: nil)
    



正如我们在ReusableImageDisplayVC 中看到的那样,我正在尝试确保以前 VC 中的 UIImage 可用,并在调试区域中打印出来

照片不是零, UIImage: 0x6040008bde20, 0, 0

我也分配给了ImageViewImagePhoto.image = photo!

但是为什么当我运行应用程序时,它没有出现?

但是如果我像下面的代码那样直接在 ReusableImageDisplayVC 中硬编码下载图像的过程,图像就会出现

class ReusableImageDisplayVC: UIViewController 

    @IBOutlet weak var ImagePhoto: UIImageView!
    var photo : UIImage?
    var something : String?

    override func viewDidLoad() 
        super.viewDidLoad()

        let imagePath = "https://***.jpg"
        let urlImage = URL(string: imagePath)

        NetworkingService.fetchData(url: urlImage!)  (result) in

            switch result 
            case .failure(let error) :
                self.showAlert(alertTitle: "Sorry", alertMessage: error.localizedDescription, actionTitle: "Back")
            case .success (let imageData):
               self.ImagePhoto.image = UIImage(data: imageData)!
            
        


        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ReusableImageDisplayVC.tapFunction(sender:)))
        tapGesture.numberOfTapsRequired = 1
        ImagePhoto.addGestureRecognizer(tapGesture)
        view.addGestureRecognizer(tapGesture)

    



    @objc func tapFunction(sender: UITapGestureRecognizer) 
        dismiss(animated: true, completion: nil)
    



这里出了什么问题?

【问题讨论】:

【参考方案1】:

当你展示ReusableImageDisplayVC 视图控制器时,displayedImage 尚未设置。这是因为您在异步调用完成之前呈现视图控制器。试试这个:

@IBAction func openImageBarButtonDidPressed(_ sender: Any) 
    NetworkingService.fetchData(url: urlImage!)  [weak self] (result) in
        var displayedImage = UIImage()
        let imagePath = "https://example.com/someimage.jpg"
        let urlImage = URL(string: imagePath)

        self?.activityIndicator.startAnimating()

        switch result 
        case .failure(let error) :
            self?.activityIndicator.stopAnimating()
            self?.showAlert(alertTitle: "Sorry", alertMessage: error.localizedDescription, actionTitle: "Back")
            return //return instead of presenting ReusableImageDisplayVC 
        case .success (let imageData):
            self?.activityIndicator.stopAnimating()
            displayedImage = UIImage(data: imageData)!
        

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let popup = storyboard.instantiateViewController(withIdentifier: "imageDisplay") as! ReusableImageDisplayVC
        popup.photo = displayedImage

        self?.present(popup, animated: true, completion: nil)
    

(注意在fetchData完成处理程序中使用[weak self]self?return

【讨论】:

对不起我是初学者,使用[弱自我]和自我?是为了防止内存泄漏不是吗? 是的,[weak self] 使闭包中对self 的每个引用都成为弱引用,这就是为什么您必须使用self? 而不是selfself 可能为零) .这样,该块就不会持有对self 的强引用。如果您在 VC 中有异步代码,有时可能会在异步代码完成之前关闭 VC。你不会在闭包中持有对不再使用的东西的强引用(内存泄漏)

以上是关于为啥我的图像没有出现在 UIImage 视图中?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的图像出现在 Android Studio 设计视图中,但在手机中运行时却没有?

多个 UIImage 视图

为啥我的 UIImage 占用这么多内存?

UIImage 没有出现

在核心动画中,红框代替 UIImage 视图移动

更改图像视图后 UIImage 未更新