0

TableView があり、データベースから取得したデータを入力しています。画像以外はすべて正常に動作します。セルの再利用動作のため、 で画像を取得していcellForRowAtIndexPathます。cellForRowAtIndexPath詳細取得機能 ( でトリガーされる) で別の要求を行う必要があるため、画像をフェッチすることにしましたviewDidLoad。これにより、他の問題が発生しています (画像 URL を保存する前にテーブルビューをリロードする)。

問題は、高速スクロールすると、ユーザー画像の表示中に再利用可能なセルがバグるということです

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 に答える