我有一个reddit帖子列表,我想显示它的缩略图(如果存在)。我有它的功能,但它非常多。有两个主要问题:
这是代码:
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("Post", forIndexPath: indexPath) as UITableViewCell
let post = swarm.posts[indexPath.row]
cell.textLabel!.text = post.title
if(post.thumb? != nil && post.thumb! != "self") {
cell.imageView!.image = UIImage(named: "first.imageset")
var image = self.imageCache[post.thumb!]
if(image == nil) {
FetchAsync(url: post.thumb!) { data in // code is at bottom, this just drys things up
if(data? != nil) {
image = UIImage(data: data!)
self.imageCache[post.thumb!] = image
dispatch_async(dispatch_get_main_queue(), {
if let originalCell = tableView.cellForRowAtIndexPath(indexPath) {
originalCell.imageView?.image = image
originalCell.imageView?.frame = CGRectMake(5,5,35,35)
}
})
}
}
} else {
dispatch_async(dispatch_get_main_queue(), {
if let originalCell = tableView.cellForRowAtIndexPath(indexPath) {
originalCell.imageView?.image = image
originalCell.imageView?.frame = CGRectMake(5,5,35,35)
}
})
}
}
return cell
}
这是加载时的应用程序 - 看起来一切正常:
然后,如果我点击图像(即使你滚动),它会调整大小:
如果你向上和向下滚动,图片就会变得笨拙(看看中间的帖子 - 泛型乐趣):
我做错了什么?
**图片和标题是从reddit中提取的,不是由我生成的**
编辑:FetchAsync类承诺:
class FetchAsync {
var url: String
var callback: (NSData?) -> ()
init(url: String, callback: (NSData?) -> ()) {
self.url = url
self.callback = callback
self.fetch()
}
func fetch() {
var imageRequest: NSURLRequest = NSURLRequest(URL: NSURL(string: self.url)!)
NSURLConnection.sendAsynchronousRequest(imageRequest,
queue: NSOperationQueue.mainQueue(),
completionHandler: { response, data, error in
if(error == nil) {
self.callback(data)
} else {
self.callback(nil)
}
})
callback(nil)
}
}
答案 0 :(得分:5)
不幸的是,这似乎是“基本”表格视图单元格的限制。我最终做的是创建一个自定义的TableViewCell。依赖Ray Wenderlich的教程,可以在这里找到:http://www.raywenderlich.com/68112/video-tutorial-table-views-custom-cells
由于代码是如此微不足道,这有点令人沮丧,但我认为从好的方面来看,这意味着它是一个“简单”的解决方案。
我的最终代码:
PostCell.swift
(所有脚手架代码)
import UIKit
class PostCell: UITableViewCell {
@IBOutlet weak var thumb: UIImageView!
@IBOutlet weak var title: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
PostsController.swift
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("PostCell", forIndexPath: indexPath) as PostCell
let post = swarm.posts[indexPath.row]
cell.title!.text = post.title
if(post.thumb? != nil && post.thumb! != "self") {
cell.thumb!.image = UIImage(named: "first.imageset")
cell.thumb!.contentMode = .ScaleAspectFit
var image = self.imageCache[post.thumb!]
if(image == nil) {
FetchAsync(url: post.thumb!) { data in
if(data? != nil) {
image = UIImage(data: data!)
self.imageCache[post.thumb!] = image
dispatch_async(dispatch_get_main_queue(), {
if let postCell = tableView.cellForRowAtIndexPath(indexPath) as? PostCell {
postCell.thumb!.image = image
}
})
}
}
} else {
dispatch_async(dispatch_get_main_queue(), {
if let postCell = tableView.cellForRowAtIndexPath(indexPath) as? PostCell {
postCell.thumb!.image = image
}
})
}
}
return cell
}
我的故事板:
答案 1 :(得分:2)
我不确定这样做的最佳方式,但这里有几个解决方案:
像其他人一样使用AFNetworking。它具有占位符图像,替换图像的异步下载和智能缓存的想法。使用可可豆荚安装,使用#import "UIImageView+AFNetworking.h"
创建两种不同类型的单元格。在使用dequeReusableCell ...在cellForRowAtIndexPath中抓取单元格之前,请检查它是否已展开。如果展开,则返回并填充展开的单元格,否则返回并填充未展开的单元格。如果单元格是“选定”单元格,则通常会对其进行扩展。
您的里程可能会有所不同
答案 2 :(得分:1)
从UITableViewDataSource的tableView实现中调用tableView.cellForRowAtIndexPath是一个巨大的错误(tableView:UITableView,cellForRowAtIndexPath indexPath:NSIndexPath) - > UITableViewCell中。相反,当完成拇指图像的异步提取时,使用图像更新模型,然后请求tableView为该特定单元格的indexPath重新加载行。让您的数据源确定正确的indexPath。如果在图像下载完成之前单元格处于屏幕外,则不会对性能产生影响。当然还有主线程上的reloadRows。