我正在学习swift / IOS,并且在将imageView设置在传递给dispatch_async(dispatch_get_main_que)
的闭包中时,要让图像显示在表格视图单元格中。
这是我返回tableview的单元格的代码。 请注意,调度调用已被注释掉。在这种状态下一切都很好。 (图像显示没有任何交互)
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(){}的闭包中时,直到我点击它或旋转设备后图像才会出现 请注意,此代码与上述代码之间的唯一区别是两行未注释。 注意;这一切都在模拟器上
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
}
答案 0 :(得分:4)
如果你不得不将图像分配放入GCD(可能用于异步图像加载),你必须调用以下方法,第二种方法是可选的,取决于你对更新频率的要求:
cell.setNeedsLayout() //invalidate current layout
cell.layoutIfNeeded() //update immediately
我想| tableView:cellForRowAtIndexPath:|隐式调用上述方法。因此,在大多数情况下,您不必关心这一点。但是如果你异步地执行它,上面的数据源方法调用这些方法的时间,根本就没有图像显示。因此,有时候稍后,您将获得图像,您必须在图像分配后明确调用它以获得正确的视图更新。
经过一些测试,数据源方法只调用两个方法| setNeedsDisplay |如果之前没有调用那么只有一次然后| setNeedsLayout |几次
答案 1 :(得分:0)
对我来说,我在textLabel下找到它, 您需要做的所有事情:
type StateA = [
{ error: "not logged in"; },
never
]
type StateB = [
{ error: "not premium"; },
never
]
type StateC = [
{ error: false; },
{ data: string }
]