UIImageView在表视图中不显示,直到点击或设备是roatated

我正在学习swift / IOS的​​过程中,并有一个问题,获取图像显示在表视图单元格中,当imageView设置在传递给dispatch_async(dispatch_get_main_que)的闭包内。

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

  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(也许是用于asynchronous图像加载),你必须调用以下方法,第二个是可选的取决于你的更新频率的愿望:

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

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

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