2015-06-18 2 views
0

Я пытаюсь добавить изображение в ячейку tableview, но не успеваю его отобразить.Swift - Добавление изображения в ячейку таблицы из библиотеки объектов

Изображение загружается из файловой системы (I println()) в качестве UIImage, но я не могу представить его в ячейку. Помещение println() после закрытия показывает, что все изображения загружаются после возвращения ячейки.

Вот мой код:

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

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! UITableViewCell 

    let note = notes[indexPath.row] 
    let nsURL = NSURL(string: note.valueForKey("url") as! String)! 
    var loadError: NSError? 
    var image: UIImage? 

    assetsLibrary!.assetForURL(nsURL, resultBlock: { (asset) -> Void in 
      if let ast = asset { 
       let iref = ast.defaultRepresentation().fullResolutionImage().takeUnretainedValue() 
       image = UIImage(CGImage: iref) 
       println("The loaded image: \(image)") 
      } 
     }, failureBlock: {(error) -> Void in 
      loadError = error 
     }) 

    cell.textLabel!.text = note.valueForKey("title") as? String 
    cell.imageView!.image = image 

    return cell 
} 

Когда я заменяю замыкание следующим загрузить изображение из самого проекта он показывает в таблице. Это заставляет меня поверить в это не из-за проблемы с тем, как создается панель рассказов.

UIImage(named: transportItems[indexPath.row]) 

Любая помощь будет очень признательна.

+0

Вы пытались выяснить, вызвана ли линия 'cell.imageView! .image = image' после того, как 'image = UIImage (CGImage: iref)'? Попробуйте переместить cell.textLabel.image = изображение в блок ... Если это сработает, я могу написать ответ –

ответ

0

Основная проблема, с которой я столкнулся, как указано в @ gnasher729, - это беспорядок на синхронных и асинхронных вызовах. Переписывая код, чтобы принять это во внимание и включить кеш, у меня есть следующее рабочее решение.

var cachedImages = [String:UIImage]() 

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

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as! UITableViewCell 
    let note = notes[indexPath.row] 
    let url = note.valueForKey("url") as! String 

    cell.textLabel!.text = note.valueForKey("title") as? String 
    cell.imageView!.image = UIImage(named: "note-icon") 

    if let image = cachedImages[url]{ 
     cell.imageView!.image = image 
    } else { 
     let nsURL = NSURL(string: url)! 
     var loadError: NSError? 

     assetsLibrary!.assetForURL(nsURL, resultBlock: { (asset) -> Void in 
      if let ast = asset { 
       let image = UIImage(CGImage: ast.defaultRepresentation().fullResolutionImage().takeUnretainedValue()) 
       self.cachedImages[url] = image 

       dispatch_async(dispatch_get_main_queue(), { 
        if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) { 
         cellToUpdate.imageView?.image = image 
        } 
       }) 

      } 
      },failureBlock: {(error) -> Void in 
       loadError = error 
     }) 
    } 
    return cell 
} 

Это может быть дополнительно улучшено, чтобы снять большую часть основной резьбы.

2

Это не работает. cellForRowAtPathIndex - это синхронная процедура. assetForURL - это асинхронная процедура. Он вернет данные долгое время после возвращения cellForRowAtPathIndex.

Вот что вы должны сделать: Имейте метод cachedAssetForURL, который немедленно возвращает актив или возвращает нуль. Если он возвращает актив, сохраните его. Помните, что это должно быть настолько эффективным, насколько это возможно, потому что это называется, когда пользователь прокручивает изображения вверх и вниз.

Если метод возвращает нуль, активируйте загрузку в фоновом режиме. Когда эта загрузка заканчивается, даже не пытайтесь сохранить изображение в ячейке - к этому времени одна и та же ячейка может отображать совершенно другой объект! Вместо этого сохраните данные, чтобы cachedAssetForURL смог вернуть актив и сделать недействительными строку вашего представления таблицы.

+0

Awesome, это действительно помогло мне понять корень моей проблемы. – tonyedwardspz

0

Огоньте уведомление в блоке (оно асинхронно), управляйте им, установив изображение и перезагрузив представление.

Смежные вопросы