我正在按照这个精彩的教程学习iOS编程,只是我的目标是iOS 9并进行了一些小的修改。
在下面的tableView()函数中,我可以下载缩略图并调用我的处理程序,这从控制台打印出的两条日志行中可以明显看出。然而,当应用程序(在模拟器中)运行时,我必须单击每个表单元格才能显示图像。我试图查看UIImageView
或表单元格中是否有refresh()
或类似的内容,但一无所获。
如何在收到数据后立即显示图像?
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: UITableViewCell = tableView.dequeueReusableCellWithIdentifier(kCellIdentifier)!
let album = self.albums[indexPath.row]
// ... setting up other cell's data, see the tutorial link
// Start by setting the cell's image to a static file
// Without this, we will end up without an image view!
cell.imageView?.image = UIImage(named: "Blank52")
let request: NSURLRequest = NSURLRequest(URL: thumbnailURL)
let urlSession = NSURLSession.sharedSession()
urlSession.dataTaskWithRequest(request, completionHandler: {(data, response, error) -> Void in
print("received thumbnail (thumbnailURLString)") // reached
if error == nil {
// Convert the downloaded data in to a UIImage object
let image = UIImage(data: data!)
// Update the cell
dispatch_async(dispatch_get_main_queue(), {
print("...dispatched thumbnail image for (thumbnailURLString)") // reached
if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) {
cellToUpdate.imageView?.image = image
}
})
}
}).resume()
return cell
}
这个部分没有意义:
if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) {
cellToUpdate.imageView?.image = image
这似乎在创造一个无限循环。对cellForRowAtIndexPath
的每次调用都会导致对cellForRowAtIndexPath
的另一次调用。
我想你的意思是:
cell.imageView?.image = image
你已经知道这个牢房了。您在调用此块之前刚刚创建了它。你不需要再查了。
我想出了一个变通办法。如果我也稍微更新了一下文本,那么图像就会直接显示出来,而不会单击表视图单元格。
cellToUpdate.imageView?.image = image
cellToUpdate.textLabel?.text = "(album.title) " // a space is added to the end to make a difference and force the cell to be updated
对我来说,这听起来像是UITableViewCell
中的一个错误(或者模拟器?还没有在真正的设备上尝试过)。
为什么你只是在没有dispatch_async(dispatch_get_main_queue())部分的情况下尝试。
dispatch_async(dispatch_get_main_queue(), {
print("...dispatched thumbnail image for (thumbnailURLString)") // reached
if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) {
cellToUpdate.imageView?.image = image
}
})
至
cell.imageView?.image = image
获取要更新的单元格时,可能需要强制转换单元格。
dispatch_async(dispatch_get_main_queue(), {
print("...dispatched thumbnail image for (thumbnailURLString)") // reached
if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) as! UITableViewCell {
cellToUpdate.imageView?.image = image
}
})
Swift 5设置图像后,只需将以下代码放入cellForRowAt委托方法中。
UIView.performWithoutAnimation {
tableView.beginUpdates()
tableView.endUpdates()
}
// Full Method
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let cell = tableView.dequeueReusableCell(withIdentifier: "PhotoCell", for: indexPath) as? PhotoCell else { return UITableViewCell() }
let model = self.arrPhotos?[indexPath.row]
// Below method download image from url using asycn
SwiftHelper.downloadImageFrom(strUrl: model?.url ?? "") {[weak self] (img) in
guard let _ = self, let image = img else { return }
print("ImgDownloaded")
cell.imgView.image = image
// cell.layoutIfNeeded()
UIView.performWithoutAnimation {
tableView.beginUpdates()
tableView.endUpdates()
}
}
return cell
}
若要对图像执行动画,可以移除performWithoutAnimation块。