从 URL 检索和显示多个图像

Posted

技术标签:

【中文标题】从 URL 检索和显示多个图像【英文标题】:Retrieve and display multiple images from URL 【发布时间】:2017-04-18 11:40:38 【问题描述】:

使用 Swift3、Alamofire 和 AlamofireImage 进行实验。我正在尝试在表格视图中显示一些 Instagram 图像。我有一个使用 Alamofire 检索到的 Placesdata.json 文件,如下所示:


  "places" : [
     "name" : "place1", "url" : "http://instagramImage1.jpg" ,
     "name" : "place2", "url" : "http://instagramImage2.jpg" ,
     "name" : "place3", "url" : "http://instagramImage3.jpg" ,
  ]

我已经用UIImageView 设置了PlaceTableViewCell,并将它连接到相应控制器的插座上。

我还有一个PlaceTableViewController,其中包括:

var places = [Place]() //empty array to store places

viewDidLoad() 方法中我调用了一个私有函数:

loadJson()

函数如下所示:

private func loadJson() 
    Alamofire.request("https://example.com/data.json").responseJSON  response in
        if let JSON = response.result.value as? [String : Any],
            let places = JSON["places"] as? [[String : String]] 
            for place in places 
                //should I call loadImage() function here?
            
        
    

我还为 JSON 文件中的每个位置创建了一个模型:

import UIKit

class Place 

    var name: String
    var url: String

    init?(name: String, url: String) 
        self.name = name
        self.url = url     
    


问题

我不知道从这里去哪里。我想使用 AlamofireImage(我已经包含在我的项目中)来下载每个图像,但我可以在某种循环中执行此操作吗?我还想在新的表格行中显示每个图像。任何建议和代码示例将不胜感激。

【问题讨论】:

在行的每个单元格中,使用 AlamofireImage 加载图像。如果您在loadJSON() 中执行此操作,您将预取所有图像,这是真的,但如果用户不滚动查看每张图像,您将一无所获。 【参考方案1】:

我建议不要在loadJSON 中获取图像。

为什么?

在初始请求中可能会返回大量照片,用户甚至可能永远无法在应用程序中向下滚动到足以看到其中的一些。

最重要的是,如果同时初始化太多请求,则某些请求可能会在等待其他请求完成时超时。所以这可能不是最好的解决方案。

所以,现在来解决问题。仅下载用户尝试查看的单元格的图像数据是有意义的。

TableView 有一个仅用于此目的的委托方法

optional func tableView(_ tableView: UITableView, 
        willDisplay cell: UITableViewCell, 
           forRowAt indexPath: IndexPath)

使用此方法加载图像。

extension ViewController: UITableViewDelegate 
   func tableView(_ tableView: UITableView, 
        willDisplay cell: UITableViewCell, 
           forRowAt indexPath: IndexPath) 

    let photoURL = places[indexPath.row].url

    // fetch this photo from web using URL

    // get the table view cell and update the image
     if let cell = self.tableView.cellForRow(at: indexPath) as UITableViewCell 
         cell.imageView.image = //fetchPhoto
        
    

【讨论】:

谢谢。 places.count 在尝试设置 numberOfRowInSection 时给了我 0。知道如何确保在设置行数之前获取 JSON 数据吗? 是否考虑将self.tableView.reloadData() 放在loadJson() 函数的末尾? 在这种情况下,如果您正在更新 mainQueue 上的图像,则无需重新加载数据。 要先获取places结果,先放到viewDidLoad中,获取mainQueue上的数据,然后重新加载tableView dataSource。 现在就试试你的扩展。这是用 Swift3 写的吗?【参考方案2】:

您可以在 tableview 控制器中使用以下代码在单元格中填充图像。为此,您还需要在 tableview 中创建一个单元格或使用 xib 创建自定义单元格。我的代码是用于从 xib 加载自定义单元格的。

 //MARK:- TableView Delegate and DataSource
func tableView(_ tableView: UITableView, numberOfRowsInSection sectionIndex: Int) -> Int 
    return places.count


func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat 
    return 200//or cell height you want


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
     var cell  = tableView.dequeueReusableCell(withIdentifier: "PlaceCell") as? PlaceCell
    if cell == nil 
        cell = (loadFromNibNamed(viewClass: PlaceCell.self) as! PlaceCell)
    

    cell?.ivCategory.af_setImage(withURL: URL(string: places[indexPath.row].url)) 
    return cell!

另请注意,一旦您从 api 获得响应,您将不得不重新加载 tableview。

【讨论】:

谢谢。我实际上并没有使用 xib 文件。我应该在我的问题中提到。

以上是关于从 URL 检索和显示多个图像的主要内容,如果未能解决你的问题,请参考以下文章

使用 AJAX Jquery 以 JSON 格式显示检索到的图像 URL

从 url 检索 jpg 图像返回 nil。但是,从 url 检索 png 图像工作正常

使用 Angular 7 从 Firebase 存储中检索图像

从文件夹中检索图像

从 android 客户端将图像存储到 Blobstore 并检索 blobkey 并上传 url 以存储在 Datastore 中。 - 盖伊

使用 getdatainbackground 从 Parse 检索多个图像(IOS - Swift)