尝试从 tableView 加载图像时,Swift View Controller 空白

Posted

技术标签:

【中文标题】尝试从 tableView 加载图像时,Swift View Controller 空白【英文标题】:Swift View Controller blank when attempting to load image from tableView 【发布时间】:2020-08-05 01:03:09 【问题描述】:

请耐心等待,因为我是新手程序员。我正在构建一个项目,用户进入他们的照片库,选择一张照片并在 tableView 中显示图像的名称。他们可以在 tableView 中选择该图像,然后它将加载该图像的完整尺寸。

问题:当我点击tableView中的row item加载图片时,新的view controller只是一个白屏,而不是之前选中的图片。

这是显示图像的视图控制器:

class DetailViewController: UIViewController 
    
    var selectedImage: String?
    @IBOutlet var image: UIImageView!
    
    override func viewDidLoad() 
        super.viewDidLoad()
        if let imageToLoad = selectedImage 
            image.image = UIImage(named: imageToLoad)
        
    
    
    override func viewWillAppear(_ animated: Bool) 
        super.viewWillAppear(animated)
        navigationController?.hidesBarsOnTap = true
    
    
    override func viewWillDisappear(_ animated: Bool) 
        super.viewWillAppear(animated)
    
    

这里是新视图的加载位置:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    
    if let dvc = storyboard?.instantiateViewController(identifier: "Detail") as? DetailViewController 
        
        dvc.selectedImage = imageArray[indexPath.row].image
        
        navigationController?.pushViewController(dvc, animated: true)
        
    
    

使用导航栏按钮项选择照片并在此处加载到 Photo 类型的 imageArray 中:

    @objc func loadImage() 
        
        let picker = UIImagePickerController()
        picker.allowsEditing = true
        picker.delegate = self
        present(picker, animated: true)
        
    
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) 
        
        guard let image = info[.editedImage] as? UIImage else  return 
        let imageName = UUID().uuidString
        let imagePath = getDocumentsDirectory().appendingPathComponent(imageName)
        
        // Convert to JPEG data
        
        if let jpegData = image.jpegData(compressionQuality: 0.8) 
            // We have a valid photo
            try? jpegData.write(to: imagePath)
        
        
        let photo = Photo(name: "Unkown", image: imageName)
        imageArray.append(photo)
        tableView.reloadData()
        
        dismiss(animated: true)
       
    
    
    func getDocumentsDirectory() -> URL 
  
        let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
        return paths[0]
    

最后是保存照片数据的 Photo 类

import UIKit

class Photo: NSObject 
    
    var name: String
    var image: String
    
    init(name: String, image: String) 
        self.name = name
        self.image = image
    
    

当新的视图控制器正在加载时,我可以看到在调试器中填充的图像名称字符串,但由于某种原因,它只是显示了一个白屏。

新的细节视图控制器

@IBOutlet var image: UIImageView!
var url = URL(string: "")

override func viewDidLoad() 
    super.viewDidLoad()

    if let data = try? Data(contentsOf: url!) 
        image.image = UIImage(data: data)            
    

    override func viewWillAppear(_ animated: Bool) 
    super.viewWillAppear(animated)
    navigationController?.hidesBarsOnTap = true


override func viewWillDisappear(_ animated: Bool) 
    //super.viewWillAppear(animated)

新的 didSelectRowAt 方法

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
    
    if let dvc = storyboard?.instantiateViewController(identifier: "Detail") as? DetailViewController 
        

        let imageName = UUID().uuidString
        let urlString = getDocumentsDirectory().appendingPathComponent(imageName)
        dvc.url = urlString
        
        navigationController?.pushViewController(dvc, animated: true)
    

【问题讨论】:

不要在viewWillDisappear中调用super.viewWillAppear 感谢您的快速回复。但是,从 tableView 中选择项目时仍然出现空白屏幕。我想知道 imageName 是否设置不正确,因此当它尝试将其分配给我的另一个视图控制器上的图像视图时不存在。我确实在我的 imageArray 中看到了一个图像名称。想法? 是的,我看到了问题所在。我会写一个答案。顺便问得很好。 【参考方案1】:

问题出在这一行:

image.image = UIImage(named: imageToLoad)

您不会以这种方式找到图像。该方法在应用程序包中查找。那不是图像所在的位置。

您需要从您放置图像的位置获取图像,在 Documents 目录中,基本上使用与保存图像相反的方式。获取 Documents 目录 url,形成图像文件 url,并使用 Data 结构从该 url 加载图像数据,然后从数据创建 UIImage。

所以,一旦你计算出这张图片的 url,你会说,就像你最初计算它以保存它的方式一样

if let data = try? Data(contentsOf: url) 
     image.image = UIImage(data: data)

【讨论】:

这就是我在 getDocumentsDirectory() 方法中我相信的倒数第二个代码块中所做的事情。我是否需要以某种方式在其他视图控制器中使用该返回值来加载图像? 这只是一个实用程序,但您当然需要推广它的范围,因为您需要在多个类中使用它。 感谢您的帮助。在玩了一会儿之后,我似乎仍然没有得到它。我所做的是在我的 DetailViewController(显示图像的位置)中创建了一个 URL 变量。在 didSelectRowAt 方法中,我将 getDocumentsDirectory() 的返回值传递给该 url 变量。然后我在上面提供的 if let 块中使用了该 url 变量。还是白屏。这听起来像是正确的实现吗? 好吧,我现在看不到您的代码。您的问题是您的代码 then 出了什么问题。我告诉了你答案。您通过将文件 URL 计算为 let imagePath = getDocumentsDirectory().appendingPathComponent(imageName) 来保存图像。您需要完全进行相同的计算,以便从保存位置读取该图像。你不能把车钥匙放在最上面的抽屉里,然后期望在裤子口袋里找到它们。 好的,但是看看你的didSelect。您正在呼叫let imageName = UUID().uuidString再次,它为此图像构成了一个不同的名称。问题是图像名称到底是什么。您需要最初保存它时给它的名称。你之前用imageArray[indexPath.row].image 正确地获取了它,现在你把它扔掉了吗?这正迅速变得愚蠢。另外,不,字符串不是 URL。做你以前做的事;获取真实姓名字符串并传递,让细节控制器计算出URL并打开图像。

以上是关于尝试从 tableView 加载图像时,Swift View Controller 空白的主要内容,如果未能解决你的问题,请参考以下文章

如何在 swift 3 中将图像从服务器加载到 tableView 单元格?

从 alamofire swift 的 tableview 单元格中的 url 加载图像

在 Swift 中加速 TableView 加载 JSON

当我尝试重新加载日期时,Swift 5 TableView 在 ViewController 中发现 nil

如何使用 Swift 3 将图像从 Rest Api 加载到视图中加载方法

为啥我在使用 kingfisher 将图像从 JSON 加载到 tableview 时出错?