0

我有一个 TableView,我正在用从数据库中检索到的数据填充它。除图像外,一切正常。由于单元格重用行为,我正在获取cellForRowAtIndexPath. 我选择获取图像是cellForRowAtIndexPath因为在详细信息检索功能(在 中触发viewDidLoad)中,我需要执行另一个请求,这会导致其他问题(在存储图像 url 之前重新加载 tableview)

问题是当我快速滚动时,可重复单元格在显示用户图像时出错

override func viewDidLoad() {
    super.viewDidLoad()
    fetchData()
}

var theUser = 

func fetchData() {
   //.. after data is retrieved

   var innerDict = [String:String]()

   if let user = details.value![key] {
      if let name = user["name"] {
         // works
         innerDict["name"] = name
       }

      if let image = user["imageName"] {
       // gets the image name but at this point I need to;
       // a) retrieve the url here (with another call), which will eventually fail
       // to catch up with `innerDict` so `innerDict` won't contain `image` variable.
       // ie;

       myRef.downloadURLWithCompletion { (URL, error) -> Void in }

      // b) Store the `image` name in innerDict and download image from url 
      // in `cellForRowAtIndexPath`. I chose this method:

        innerDict["image"] = image
      }

   user[id] = innerDict
   tableView.reloadData()
}

现在tableView照常了。

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

   let cell = ...

   // more stuff

   if let imageName = user["image"] {
      let storage = FIRStorage.storage()
      let storageRef = storage.referenceForURL("gs://bucket.com").child(user[id]).child(imageName)

      storageRef.downloadURLWithCompletion { (URL, error) -> Void in
           if (error != nil) {
              // handle 
           } else {
              // I thought using Haneke would help to cache the image
               cell.image.hnk_setImage(URL!)
           }
      }
 }

这是我能到达的最近的一个。但是,当我快速滚动时,图像会显示错误。


编辑:

我也尝试过使用这种方法,但是使用这种方法会多次下载相同的图像,因此显示相同的图像需要时间。

islandRef.dataWithMaxSize(1 * 1024 * 1024) { (data, error) -> Void in
  if (error != nil) {
    // Uh-oh, an error occurred!
  } else {
    let image: UIImage! = UIImage(data: data!)
    cell.userImage.hnk_setImage(image, key: "\(userID)")
  }
}

但是,使用顶部方法时,速度非常快。上面代码的唯一问题是我快速滚动时出现的故障。


编辑 2

 var images = [UIImage]()

 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCellWithIdentifier("ItemCell", forIndexPath: indexPath) as! ItemDetailTableViewCell

let item = items[indexPath.section][indexPath.row]

if let uid = item["owner"] as? String {
   if let user = users[uid] {
      if let imageName = user["image"] { 
         if let img: UIImage = images[indexPath.row] {    // crash here "fatal error: Index out of range"
           cell.userImage.image = img
          }
      } else {
        let storage = FIRStorage.storage()
        let storageRef = storage.referenceForURL("gs://bucket").child(uid).child(imageName)

        storageRef.downloadURLWithCompletion { (URL, error) -> Void in
           if (error != nil) {

            } else {
               dispatch_async(dispatch_get_main_queue(), {
                     cell.userImage.hnk_setImageFromURL(URL!)
                     self.images[indexPath.row] = cell.image.image!
               })
           }
         }
    }   
}





}    
4

1 回答 1

0

我认为您应该从 url 保存图像并在单元格要重用时显示图像,希望这可以解决您的故障

 var myImages =  [String: UIImage]()


 func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
     let cell = tableView.dequeueReusableCellWithIdentifier("ItemCell", forIndexPath: indexPath) as! ItemDetailTableViewCell
     let item = items[indexPath.section][indexPath.row]

    if let img: UIImage = myImages["\(indexPath.section)\(indexPath.row)"] {
        cell.image.image = img
    } else {
      if let uid = item["owner"] as? String {
        if let imageName = user["image"] {
           let storage = FIRStorage.storage()
           let storageRef = storage.referenceForURL("gs://bucket.com").child(user[id]).child(imageName)
           storageRef.downloadURLWithCompletion { (URL, error) -> Void in
               if (error != nil) {
                  cell.image = UIImage(named: "placeholder") // put default Image when failed to download Image
               } else {
                  dispatch_async(dispatch_get_main_queue(), {
                   cell.image.hnk_setImage(URL!)
                   // Store the image in to our cache
                   self.myImages["\(indexPath.section)\(indexPath.row)"]= cell.image.image
                })
              }
         }
      }
    }

}
于 2016-06-16T08:39:23.540 回答