table 视图中的 UIImageView 在单击或旋转设备之前不会显示

UIImageView in table view not showing until clicked on or device is roatated

我正在学习 swift/IOS,当 imageView 设置在传递给 [=13= 的闭包中时,在 table 视图单元格中显示图像时遇到问题].

这是我返回 table 视图的单元格的代码。 注意调度调用被注释掉了。在这种状态下一切正常。 (图像显示没有任何交互)

  override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell: UITableViewCell
    if indexPath.section == 3 {
      cell = tableView.dequeueReusableCellWithIdentifier("imageCell", forIndexPath: indexPath) as! MentionedImageTableViewCell
      if let images = tweetSections?[3].items as? [MediaItem] {
        let imageUrl = images[indexPath.row].url
        let qos = Int(QOS_CLASS_USER_INTERACTIVE.value)
        let queue = dispatch_get_global_queue(qos, 0)
        println("feching image for cell = \(cell)")
//      dispatch_async(queue) {
          if let imageData = NSData(contentsOfURL: imageUrl), let image = UIImage(data: imageData) {
            println("fetch complete")
//          dispatch_async(dispatch_get_main_queue()) {
              println("posting image = \(image), to cell = \(cell)")
              cell.imageView?.image = image
              println("cells image = \(cell.imageView?.image)")
//          }
          }
//      }
      }
    } else {
      cell = tableView.dequeueReusableCellWithIdentifier("textCell", forIndexPath: indexPath) as! UITableViewCell
      if let keywords = tweetSections![indexPath.section].items as? [Tweet.IndexedKeyword] {
        let text = keywords[indexPath.row].keyword
        cell.textLabel?.text = text
      }
    }
    return cell
  }

但是当我将更新包装在传递给 dispatch_async(get_main_que() {} 的闭包中时,图像只有在我点击它或旋转设备后才会出现 请注意,此代码与上面的代码之间的唯一区别是有两行未注释。 笔记;这一切都在模拟器上

  override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell: UITableViewCell
    if indexPath.section == 3 {
      cell = tableView.dequeueReusableCellWithIdentifier("imageCell", forIndexPath: indexPath) as! MentionedImageTableViewCell
      if let images = tweetSections?[3].items as? [MediaItem] {
        let imageUrl = images[indexPath.row].url
        let qos = Int(QOS_CLASS_USER_INTERACTIVE.value)
        let queue = dispatch_get_global_queue(qos, 0)
        println("feching image for cell = \(cell)")
//      dispatch_async(queue) {
          if let imageData = NSData(contentsOfURL: imageUrl), let image = UIImage(data: imageData) {
            println("fetch complete")
            dispatch_async(dispatch_get_main_queue()) {
              println("posting image = \(image), to cell = \(cell)")
              cell.imageView?.image = image
              println("cells image = \(cell.imageView?.image)")
            }
          }
//      }
      }
    } else {
      cell = tableView.dequeueReusableCellWithIdentifier("textCell", forIndexPath: indexPath) as! UITableViewCell
      if let keywords = tweetSections![indexPath.section].items as? [Tweet.IndexedKeyword] {
        let text = keywords[indexPath.row].keyword
        cell.textLabel?.text = text
      }
    }
    return cell
  }

如果你不得不将图像赋值到GCD中(可能是为了异步图像加载),你必须调用以下方法,第二个是可选的,取决于你对更新频率的期望:

cell.setNeedsLayout() //invalidate current layout
cell.layoutIfNeeded() //update immediately

我猜 |tableView:cellForRowAtIndexPath:|隐式调用上述方法。所以在大多数情况下你不必关心这个。但是如果你是异步的,上面的数据源方法调用这些方法的时候,根本就没有图像可以显示。所以有时稍后,你得到图像,你必须在图像分配后显式调用它以获得正确的视图更新。

经过一些测试,数据源方法只是调用了两个方法|setNeedsDisplay|如果之前没有调用,则只调用一次,然后 |setNeedsLayout|几次

对我来说,我在 textLabel 下找到它, 您需要做的一切:

cell.textLabel?.backgroundColor = .clear