2017-09-04 18 views
2

我有一个呈现注释的表视图。每条评论都包含一个标签和一个提供作者个人资料图片的UIImage。加载表格时图像出现的方式没有模式。有时他们加载罚款。其他时候,占位符图像出现,图像永不加载。如果我滚动,行为会有所不同。我正在使用AlamofireImage加载图像时UITableViewCells中的零星行为

经过一番研究,我发现这个帖子里的建议是呼吁

self.tableView.beginUpdates() 
self.tableView.endUpdates() 

在AlamofireImage的完成处理程序。这根本没有效果。

这里是我的原代码:

func tableView(_ tableView: UITableView, cellForRowAt.....{ 
... 
    let myURL = Comment.profileImageURL 
      if Comment.profileImageURL != nil { 
       profileImage.af_setImage(withURL: myURL!, placeholderImage: #imageLiteral(resourceName: "Profile Image")) 
      } else { 
       profileImage.image = UIImage(named: "Profile Image") 
      } 

这里是基于this question's recommendation更新(在页面上最后的答案):

let myURL = comment.profileImageURL 
    if comment.profileImageURL != nil { 
      cell.profileImage.af_setImage(
          withURL: myURL!, 
          placeholderImage: #imageLiteral(resourceName: "Profile Image"), 
          filter: nil, 
          imageTransition: UIImageView.ImageTransition.crossDissolve(0.5), 
          runImageTransitionIfCached: false) { 
           // Completion closure 
           response in 
           // Check if the image isn't already cached 
           if response.response != nil { 
            // Force the cell update 
            self.tableView.beginUpdates() 
            self.tableView.endUpdates() 
           } 
         } 
    } else { 
      cell.profileImage.image = UIImage(named: "Profile Image") 
     } 

==== ====编辑

添加额外的信息,希望它会有所帮助: 我试过按照下面的建议设置profileImage.image = nil。我也取消了下面建议的prepareForReuse()的下载无效。

调用图像之前,我做的UIImageView

profileImage.layer.cornerRadius = profileImage.bounds.size.width/2 
profileImage.clipsToBounds = true 
profileImage.layer.borderWidth = 2 
profileImage.layer.borderColor = UIColor(red:222/255.0, green:225/255.0, blue:227/255.0, alpha: 1.0).cgColor 

下面的一些配置是ImageView的XCode中设置: enter image description here

最后的问题本身。大约50%的时间我在视图或滚动之间来回移动,占位符图像出现在实际图像的位置。事实上。占位符经常出现在第一次加载。

enter image description hereenter image description here

===编辑#2 ===

我试图按照阿什利米尔斯第二个建议。我检查AlamofireImage完成处理程序中的图像URL,结果很奇怪。我只是加载了表格视图。如下图所示装精的所有图片:

enter image description here

我打印出来的图像URL时完成处理火灾和它看起来罚款:

我在完成 可选的是(http://www.smarttapp.com/Portals/0/Users/018/18/18/sballmer.jpg) 我在完成 可选(http://www.smarttapp.com/Portals/0/Users/018/18/18/sballmer.jpg) 我在完成 可选(http://www.smarttapp.com/Portals/0/Users/011/11/11/Elon%20Musk.jpeg) 我在完成 可选(http://www.smarttapp.com/Portals/_default/Users/001/01/1/Martin%20Profile.jpg

使用导航栏,我退了出来,然后重新和图像的显示的所有占位符图片:

enter image description here

打印出如下:

我已完成无 我已完成无 我已完成无

最后,这是图像加载代码并完成处理:我在这一点上都试过了

let myURL = Comment.profileImageURL 
     if Comment.profileImageURL != nil { 
      // profileImage.af_setImage(withURL: myURL!, placeholderImage: #imageLiteral(resourceName: "Profile Image")) 
      profileImage.af_setImage(
       withURL: myURL!, 
       placeholderImage: #imageLiteral(resourceName: "Profile Image"), 
       filter: nil, 
       completion:{ image in 
        print("I'm in completion") 
        print(image.response?.url) 
        self.setNeedsLayout() 
        self.layoutIfNeeded() 
      }) 

     } else { 
      profileImage.image = UIImage(named: "Profile Image") 
     } 

。请帮忙。

回答

0

UITableViewControllerreuses cells。为了防止旧图像再次出现在尚未完全加载的单元中,请在加载之前将单元格的图像设置为nil

cell.profileImage.image = nil 

let myURL = comment.profileImageURL 

if comment.profileImageURL != nil { 
    [...] 
} else { 
    cell.profileImage.image = UIImage(named: "Profile Image") 
} 
+0

the4kman,谢谢你的建议。我跑了测试,可悲的是这并没有解决问题,虽然它似乎有改善的东西。当图像确实可用时,我仍然可以获取占位符图像(需要下载) –

0

如果从屏幕上滚动出来,您在图像中显示的每个单元格都可以重复使用。使用af_setImage将获取图像,并在接收到响应时显示该图像,但到那时该单元格可能会被重用,并试图在不同的URL上显示图像。

您可以通过两种方式处理这个问题,但首先要做的是一个Comment财产有添加到您的细胞,并处理下载,而不是在视图控制器(你可能会发现使你的所有IBOutlet性能fileprivate这种帮助 - 它确保你不能从视图控制器更新单元格的UI)

1)当电池被重用取消下载请求......

override func prepareForResuse() { 
    profileImage.af_cancelImageRequest 
} 

这可以防止响应对于之前的URL被返回,但意味着图像不是这样做的wnloaded。

2)检查响应的URL是你期望的。

var requestedURL: URL? 
var comment: Comment? { 
    didSet { 
     if let myURL = Comment.profileImageURL { 
      requestedURL = myURL 

      // Fetch image from URL and when response is received, 
      // check self.myURL == response.url 

     } else { 
      profileImage.image = UIImage(named: "Profile Image") 
     } 
    } 
} 

这样,即使没有显示图片,图片仍然会被下载。

+0

我试图在此处遵循您的解决方案。所以首先,在cellForRowAt中,我有一个configureCell()函数,它调用一个UITableViewCell子类,并在其中配置单元。你在哪里建议打电话给prepareForReuse?在我调用configureCell之前? –

+0

'prepareForReuse'是一个'UITableViewCell'方法,每次单元重用时都会自动调用它。你不要自己打电话。 –

+0

Ashley,我实现了prepareForReuse。我不清楚你的第二个建议。当我将注释对象传递给configureCell()时,我有了所需的profileImageURL(comment.profileImageURL。)所以,当AlamofireImage完成下载时你说,我应该将所需的URL与返回的URL进行比较。我在阿拉莫的完成处理程序中这样做吗?如果他们不一样,那么会发生什么? –

相关问题