表视图中的 UIImageView 在单击或设备旋转之前不显示 [英] UIImageView in table view not showing until clicked on or device is roatated

查看:22
本文介绍了表视图中的 UIImageView 在单击或设备旋转之前不显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在学习 swift/IOS,并且在传递给 dispatch_async(dispatch_get_main_que) 的闭包中设置 imageView 时,在获取图像以显示在表格视图单元格中时遇到问题.

I am in the process of learning swift/IOS and having a problem with getting an image to display in a table view cell when the imageView is set within a closure passed to dispatch_async(dispatch_get_main_que).

这是我返回表格视图单元格的代码.请注意,调度调用已被注释掉.在这种状态下一切正常.(图片显示无任何交互)

Here is my code for returning the cell for the tableview. Notice that the dispatch calls are commented out. In this state everything is OK. (the image is displayed with out any interaction)

  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() {} 的闭包中时,直到我单击它或旋转设备后图像才会出现请注意,此代码与上述代码之间的唯一区别是两行未注释.笔记;这一切都在模拟器上

But when I wrap the update in a closure passed to dispatch_async(get_main_que() {}, then the image does not appear until after I click on it or rotate the device Notice that the only difference between this code and the above is two lines that are un-commented. Note; This is all on the simulator

  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 中(可能是为了异步图片加载),你必须调用以下方法,第二个是可选的取决于您希望更新频率:

If somehow you have to put the image assignment into the GCD(maybe for asynchronous image loading), you have to call the following methods, the second one is optional depends on your desire of update frequency:

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

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

I guess the |tableView:cellForRowAtIndexPath:| calls the above methods implicitly. So in most cases you don't have to care about that. But if you do it asynchronously, the time the above data source method calls these methods, there is no image to show at all. So sometimes later, you get the image, you have to call it explicitly after image assignment to get proper view updates.

经过一些测试,数据源方法简单地调用了两个方法|setNeedsDisplay|如果之前未调用,则仅一次,然后 |setNeedsLayout|几次

After some testing, the data source method simply calls two methods |setNeedsDisplay| only once if not called before and then |setNeedsLayout| couple of times

这篇关于表视图中的 UIImageView 在单击或设备旋转之前不显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆