【问题标题】:UITableViewCell image not shown until selectedUITableViewCell 图像在选择之前不显示
【发布时间】:2015-05-04 17:41:31
【问题描述】:

我的 UITableViewCells 图像一直显示,直到我向上滚动,因此在选择单元格之前不会显示图像。

当我从另一个 ViewController 切换到初始 ViewController*(包含图像)*时也会发生同样的问题

我检查了图片的imgURL是否正确。

使用的库是:用于图像的 AFNetworking

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("FeedCell", forIndexPath: indexPath) as! MyCell
    cell.itemImageView.image = nil
    self.configureCell(cell, atIndexPath: indexPath)
    return cell
}

// AFNetworking download and display image
func uploadIMG(cell:MyCell,imgURL:NSURL,placeholderIMG:String,atIndexPath indexPath: NSIndexPath) {

    var imageRequest: NSURLRequest = NSURLRequest(URL: imgURL)
    cell.itemImageView!.setImageWithURLRequest(imageRequest, placeholderImage: UIImage(contentsOfFile: "logo.png"), success: { [weak cell] request,response,image in

        if (cell != nil) {
            cell!.itemImageView.image = image
        }}        
        , failure: nil)
}

// called from cellForRowAtIndexPath, retrieve img url to update image
func configureCell(cell: MyCell, atIndexPath indexPath: NSIndexPath) {
    let item = self.items[indexPath.row] as MWFeedItem
    var URLofImage: NSURL = NSURL(string: item.link)!
    var session = NSURLSession.sharedSession()
    let task = session.dataTaskWithURL(URLofImage, completionHandler: {(data,response, error) in
        let text = NSString(data: data, encoding: NSUTF8StringEncoding)
        var home = HTMLDocument(data: data, contentTypeHeader: text as! String)
        var div = home.nodesMatchingSelector("img")
        var urlString = div[1].firstNodeMatchingSelector("img")
        let urlData = (urlString as HTMLElement).firstNodeMatchingSelector("img")
        var urlFinal = urlData.attributes["src"]! as! String

        if urlFinal != "/images/system/bookmark-shorturl.png" {
            // call updateIMG function
            self.uploadIMG(cell, imgURL: NSURL(string: "http:www.animenewsnetwork.com" + urlFinal)!, placeholderIMG: "logo.png",atIndexPath: indexPath)
        }
    })

问题的图像表示(初始图像工作正常)

第二张图片(我向下滚动然后向上滚动,图片没有显示)

我选择了一些单元格,然后这些单元格的图像就会出现

【问题讨论】:

    标签: ios objective-c uitableview swift afnetworking


    【解决方案1】:

    尝试将图像设置为单元格后,通过调用方法tableView:reloadRowsAtIndexPaths:withRowAnimation 在表格视图中更新该单元格。或者使用自定义图像视图编写自定义单元格。请不要忘记图像设置代码必须在主线程中运行。

    【讨论】:

    • 我尝试使用该方法,但我的图像不显示或出现在错误的位置。我正在使用 UITableViewCell 的子类和我自己的自定义图像。
    • @vasyl 这是重新计算单元格布局的一种非常巧妙的方法。
    • @chiken 记住 TableView 重用单元格。所以图像属性可能是从以前的数据中设置的。在configureCell 中添加cell.itemImageView.image = nil 应该会清除旧图像。
    • @Tobias 我尝试将其设置为 nil 但图像仅在我选择单元格后才会出现
    • @chiken 让我建立一个测试项目,看看我是否可以复制问题。
    【解决方案2】:

    问题是我的图像没有设置在主线程上。为了解决这个问题,我简单地使用了下面的代码来确保我的图像会被立即设置。

    dispatch_async(dispatch_get_main_queue(), {
     // do image functions here
    
    )}
    

    【讨论】:

      【解决方案3】:

      误读了问题,但保留此内容以防有人遇到类似问题,但使用自动布局。

      我相信您正在使用自动布局。因此,如果 imageView 的帧大小是使用固有内容大小,它的图像大小,当没有图像时它将是 CGSizeZero。首次显示单元格时没有图像,因为需要下载。然后图像被下载并分配给 imageView.image。这不会自动使布局无效。您需要这样做,以便根据图像的大小重新计算 imageView 框架。它在滚动并向后滚动或选择它后显示的原因是因为当时已经下载了图像,并且当它再次显示或选择时重新计算单元格布局。

      下面是我的 TestCell 和 TestViewController

      import UIKit
      import AFNetworking
      
      class TestCell : UITableViewCell {
          static let cellIdentifier = "TestCell"
      
          @IBOutlet var downloadedImageView: UIImageView!
          @IBOutlet var rowLabel: UILabel!
          @IBOutlet var statusLabel: UILabel!
      
      }
      
      
      class TestTableViewController: UITableViewController {
      
          override func viewDidLoad() {
              super.viewDidLoad()
              // Do any additional setup after loading the view, typically from a nib.
              tableView.rowHeight = 100
          }
      
          override func didReceiveMemoryWarning() {
              super.didReceiveMemoryWarning()
              // Dispose of any resources that can be recreated.
          }
      
          override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
              return 30;
          }
      
          override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
      
              let cell = tableView.dequeueReusableCellWithIdentifier(TestCell.cellIdentifier, forIndexPath: indexPath) as! TestCell
      
              let randomName = "\(Random.firstName().lowercaseString).\(Random.lastName().lowercaseString)"
              let randomImageURL = NSURL(string: Random.avatarImageURL(name: randomName))!
      
              cell.rowLabel.text = String(indexPath.row)
              cell.statusLabel.text = "Not Downloaded"
      
              var imageRequest: NSURLRequest = NSURLRequest(URL: randomImageURL)
              cell.downloadedImageView.setImageWithURLRequest(imageRequest, placeholderImage: UIImage(named: "placeholder.png"),
                  success: { [weak cell]
                      (request, response, image) in
                      if let cell = cell {
                          cell.downloadedImageView.image = image
                          cell.rowLabel.text = String(indexPath.row)
                          cell.statusLabel.text = "Downloaded"
                      }
                  },
                  failure: { [weak cell]
                      (request, response, error) in
                      if let cell = cell {
                          cell.downloadedImageView.image = nil
                          cell.rowLabel.text = String(indexPath.row)
                          cell.statusLabel.text = "Failed: \(error.localizedDescription)"
                      }
                  })
      
              return cell
      
          }
      
      
      
      }
      
      //
      //  Random.swift
      
      import Foundation
      
      
      class Random {
      
      
          static let firstNames = ["Tora", "Shasta", "Camelia", "Gertrudis", "Charita", "Donita", "Debbra", "Shaquana", "Tommy", "Shara", "Ignacia", "Cassondra", "Melynda", "Lisette", "Herman", "Rhoda", "Farah", "Tim", "Tonette", "Johnathon", "Debroah", "Britni", "Charolette", "Kyoko", "Eura", "Nevada", "Lasandra", "Alpha", "Mirella", "Kristel", "Yolande", "Nelle", "Kiley", "Liberty", "Jettie", "Zoe", "Isobel", "Sheryl", "Emerita", "Hildegarde", "Launa", "Tanesha", "Pearlie", "Julianna", "Toi", "Terina", "Collin", "Shamika", "Suzette", "Tad"]
      
          static let lastNames = ["Austen", "Kenton", "Blomker", "Demars", "Bibbs", "Eoff", "Alcantara", "Swade", "Klinefelter", "Riese", "Smades", "Fryson", "Altobelli", "Deleeuw", "Beckner", "Valone", "Tarbox", "Shumate", "Tabone", "Kellam", "Dibiase", "Fasick", "Curington", "Holbrook", "Sulzer", "Bearden", "Siren", "Kennedy", "Dulak", "Segers", "Roark", "Mauck", "Horsman", "Montreuil", "Leyva", "Veltz", "Roldan", "Denlinger", "James", "Oriley", "Cistrunk", "Rhodes", "Mcginness", "Gallop", "Constantine", "Niece", "Sabine", "Vegter", "Sarnicola", "Towler"]
      
      
          class func int(#min: Int, max: Int) -> Int {
              return Int(arc4random_uniform(UInt32(max-min))) + min //???: RTFM on arc4random, might be need (max+1)-min.
          }
      
          class func int(#range: Range<Int>) -> Int {
              return int(min: range.startIndex, max: range.endIndex)
          }
      
          class func selectElement<T>(#array: [T]) -> T {
              return array[int(range: 0..<array.count)]
          }
      
      
          class func firstName() -> String {
              return Random.selectElement(array: Random.firstNames)
          }
      
          class func lastName() -> String {
              return Random.selectElement(array: Random.lastNames)
          }
      
          class func avatarImageURL(var name: String? = nil) -> String {
      
              if name == nil {
                  name = "(Random.firstName().lowercaseString).Random.lastName().lowercaseString"
              }
      
              let avatarImageSize = Random.int(min: 40, max: 285)
              return "http://api.adorable.io/avatars/\(avatarImageSize)/\(name!)@gmail.png"
          }
      
      
          class func imageURL() -> String {
      
              let imageWidth = Random.int(min:120, max:1080)
              let imageHeight = Random.int(min:120, max:1080)
      
              return "http://lorempixel.com/g/\(imageWidth)/\(imageHeight)/"
          }
      
      }
      

      【讨论】:

      • 我对此很陌生,但我使用的是自定义 UITableViewCell,并在情节提要上实现了固定框架。我目前的理解是,由于我对图像使用 AspectFill 和自定义 UIImageView,所以图像框架不应该改变?
      • @chiken 是的。我想我第一次回答时误读了你的问题。我认为第一次显示单元格时没有显示图像。所以我现在认为问题在于 tableview 单元格的重用。尝试在configureCell 中使用cell.itemImageView.image = nil 清除旧数据。
      • @chiken 我看到了与您的问题类似的问题。有人建议你在主线程上设置图像时仔细检查。
      • 您介意发布代码修复吗?所以如果我遇到问题,我会知道该怎么做?
      • 将其添加为下面的答案,这是我所做的修改。我在使用 AFNetworking 从 Web 获取 IMG 之前将其放置。
      【解决方案4】:

      当您滚动时,单元格将重新加载。 (您重新加载以重新下载图像)-> 这是问题。

      已解决: 下载后创建数组保存图像数据。

      并且单元格从这个数组中获取图像,而不是重新下载

      希望对您有所帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-07
        • 2016-06-10
        • 2016-02-05
        • 2014-08-06
        相关资源
        最近更新 更多