异步加载图像不断导致图像闪烁?

时间:2015-05-20 18:17:38

标签: ios facebook swift asynchronous

我有每个UITableViewCell的标题视图。在此标题视图中,我通过Facebook API中的异步函数加载个人的图片。但是,由于该函数是异步的,我相信该函数被反复调用多次,导致图像不断闪烁。我想这个问题的解决办法是首先将viewDidLoad中的图像加载到数组中,然后在UITableViewCell的标题视图中显示数组内容。但是,由于函数的异步性,我无法实现这一点:我似乎无法抓取每张照片,然后继续我的程序。这是我的尝试:

    //Function to get a user's profile picture
    func getProfilePicture(completion: (result: Bool, image: UIImage?) -> Void){
        // Get user profile pic
        let url = NSURL(string: "https://graph.facebook.com/1234567890/picture?type=large")
        let urlRequest = NSURLRequest(URL: url!)
        //Asynchronous request to display image
        NSURLConnection.sendAsynchronousRequest(urlRequest, queue: NSOperationQueue.mainQueue()) { (response:NSURLResponse!, data:NSData!, error:NSError!) -> Void in
            if error != nil{
                println("Error: \(error)")
            }
            // Display the image
            let image = UIImage(data: data)
            if(image != nil){
                completion(result: true, image: image)
            }
        }
    }
    override func viewDidLoad() {
      self.getProfilePicture { (result, image) -> Void in
          if(result == true){
              println("Loading Photo")
              self.creatorImages.append(image!)
          }
          else{
              println("False")
          }
      }
    }

    func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
      //Show section header cell with image
      var cellIdentifier = "SectionHeaderCell"
      var headerView = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as! SectionHeaderCell
      headerView.headerImage.image = self.creatorImages[section]
      headerView.headerImage.clipsToBounds = true
      headerView.headerImage.layer.cornerRadius = headerView.headerImage.frame.size.width / 2
      return headerView
    }

正如上面的程序所示,我创建的名为self.creatorImages的全局数组,其中包含我从Facebook API获取的图像数组始终为空,我需要等待"在实际使用之前,所有图片都要填充数组。我不确定如何实现这一点,因为我在我的getProfilePicture函数中尝试了一个完成处理程序,但这似乎没有帮助,这是我学会处理异步函数的一种方法。还有其他想法吗?谢谢!

1 个答案:

答案 0 :(得分:1)

我有同样的问题,但我的是在Objective-C 好吧,结构没有那么不同,我所做的是添加条件: headerView.headerImage.image

这是一个改进的解决方案,我认为适合您的实施。 由于您将self.getProfilePicture放在viewDidLoad内,因此只会调用一次section == 0只会包含图片,

如果self.creatorImages索引超出范围/界限,下面的代码会请求添加图片

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
      //Show section header cell with image
      var cellIdentifier = "SectionHeaderCell"
      var headerView = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as! SectionHeaderCell


      if (section < self.creatorImages.count) // validate self.creatorImages index to prevent 'Array index out of range' error
      {
          if (headerView.headerImage.image == nil) // prevents the blinks
          {
              headerView.headerImage.image = self.creatorImages[section];
          }
      }
      else // requests for additional image at section
      {
          // this will be called more than expected because of tableView.reloadData()
          println("Loading Photo")

          self.getProfilePicture { (result, image) -> Void in
              if(result == true) {
                  //simply appending will do the work but i suggest something like:

                  if (self.creatorImages.count <= section)
                  {
                      self.creatorImages.append(image!)

                      tableView.reloadData()

                      println("self.creatorImages.count \(self.creatorImages.count)")
                  }
                 //that will prevent appending excessively to data source
              }
              else{
                  println("Error loading image")
              }
          }
      }

      headerView.headerImage.clipsToBounds = true
      headerView.headerImage.layer.cornerRadius = headerView.headerImage.frame.size.width / 2
      return headerView
    }

你确实从我的想法中得到了不同的实现,但编辑历史中的代码并非徒劳,对吧?哈哈哈哈。;) 希望我能帮助你......干杯!