在 UITableView 中滚动时重复图像 Swift
Repeating images when scrolling in UITableView Swift
根据以下答案编辑代码
我想要什么
图片大小正确,位置正确
我得到了什么
滚动时到处随机出现一堆图片
我看了这么多答案,还是没有找到解决问题的方法。似乎每个人都有不同的问题,这里的大多数问题都在 Objective-C 中,这无济于事。我发现很难从一种转换成另一种。
我只会展示我的 table 视图函数并解释我的代码,也许有人可以找出问题所在或帮助我找出问题并自行解决。
---------------------------------------- ------------------------------------------
说明
并非所有新闻项目(单元格)都包含图片。正如您所看到的(在下面的第一个函数中),我循环遍历各个部分和嵌套的单元格,如果新闻项包含图片 if newslists[i][j] != "None
,我会显示该图像。从这一点来看,它是熟悉的代码,从教程中看到here
在第二个函数中,我再次循环遍历部分和单元格,直到找到一个应该包含图像的单元格。然后我更改此单元格的高度,以便图像适合内部。
差不多就是这样...
有什么想法吗?
---------------------------------------- ------------------------------------------
CellForRowAtIndexPath
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("NewsCell", forIndexPath: indexPath) as! UITableViewCell
if newslists[indexPath.section][indexPath.row].imageURL != "None"{
let urlString = newslists[indexPath.section][indexPath.row].imageURL
let imgURL = NSURL(string: urlString)
cell.imageView?.image = UIImage(named: "first") // placeholder
if let img = imageCache[urlString] {
cell.imageView?.image = img
println("loaded from cache")
}
else {
let request: NSURLRequest = NSURLRequest(URL: imgURL!)
let mainQueue = NSOperationQueue.mainQueue()
NSURLConnection.sendAsynchronousRequest(request, queue: mainQueue, completionHandler: { (response, data, error) -> Void in
if error == nil {
let image = UIImage(data: data)
self.imageCache[urlString] = image
dispatch_async(dispatch_get_main_queue(), {
if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) {
cellToUpdate.imageView?.image = image
println("succesfully downloaded image")
println("size of cache is \(self.imageCache.count)")
}
})
}
else {
println("Error: \(error.localizedDescription)")
}
})
}
}
cell.backgroundColor = UIColor(red: 52/255, green: 138/255, blue: 169/255, alpha: 1.0)
return cell
}
我还有一项功能可能会导致问题,但我对此表示怀疑:
HeightForRowAtIndexPath
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if newslists[indexPath.section][indexPath.row].imageURL != "None"{
println("Expanding cell for \(indexPath.section) \(indexPath.row)")
return 190.0
}
return 70.0
}
我不确定你为什么在这两种方法中都有一个双 for 循环。为每个可能的 indexPath 调用,因此您可以使用 indexPath 部分和行获取适当的数据。
您可以试试这个代码,我看不出有什么理由不能用。
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("NewsCell", forIndexPath: indexPath) as! UITableViewCell
cell.imageView?.image = nil
if newslists[indexPath.section][indexPath.row].imageURL != "None"{
let urlString = newslists[indexPath.section][indexPath.row].imageURL
let imgURL = NSURL(string: urlString)
cell.imageView?.image = UIImage(named: "first") // placeholder
if let img = imageCache[urlString] {
cell.imageView?.image = img
println("loaded from cache")
}
else {
...
}
}
return cell
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if newslists[indexPath.section][indexPath.row].imageURL != "None"{
println("Expanding cell for \(i) \(j)")
return 190.0
}
return 70.0
}
我们需要做的就是使用prepareForReuse()
函数。正如 this 中篇文章中所讨论的,此函数在单元格重用之前调用,让您取消当前请求并执行重置。
override func prepareForReuse() {
super.prepareForReuse()
imageView.image = nil
}
根据以下答案编辑代码
我想要什么
图片大小正确,位置正确
我得到了什么
滚动时到处随机出现一堆图片
我看了这么多答案,还是没有找到解决问题的方法。似乎每个人都有不同的问题,这里的大多数问题都在 Objective-C 中,这无济于事。我发现很难从一种转换成另一种。
我只会展示我的 table 视图函数并解释我的代码,也许有人可以找出问题所在或帮助我找出问题并自行解决。
---------------------------------------- ------------------------------------------
说明
并非所有新闻项目(单元格)都包含图片。正如您所看到的(在下面的第一个函数中),我循环遍历各个部分和嵌套的单元格,如果新闻项包含图片 if newslists[i][j] != "None
,我会显示该图像。从这一点来看,它是熟悉的代码,从教程中看到here
在第二个函数中,我再次循环遍历部分和单元格,直到找到一个应该包含图像的单元格。然后我更改此单元格的高度,以便图像适合内部。
差不多就是这样... 有什么想法吗?
---------------------------------------- ------------------------------------------
CellForRowAtIndexPath
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("NewsCell", forIndexPath: indexPath) as! UITableViewCell
if newslists[indexPath.section][indexPath.row].imageURL != "None"{
let urlString = newslists[indexPath.section][indexPath.row].imageURL
let imgURL = NSURL(string: urlString)
cell.imageView?.image = UIImage(named: "first") // placeholder
if let img = imageCache[urlString] {
cell.imageView?.image = img
println("loaded from cache")
}
else {
let request: NSURLRequest = NSURLRequest(URL: imgURL!)
let mainQueue = NSOperationQueue.mainQueue()
NSURLConnection.sendAsynchronousRequest(request, queue: mainQueue, completionHandler: { (response, data, error) -> Void in
if error == nil {
let image = UIImage(data: data)
self.imageCache[urlString] = image
dispatch_async(dispatch_get_main_queue(), {
if let cellToUpdate = tableView.cellForRowAtIndexPath(indexPath) {
cellToUpdate.imageView?.image = image
println("succesfully downloaded image")
println("size of cache is \(self.imageCache.count)")
}
})
}
else {
println("Error: \(error.localizedDescription)")
}
})
}
}
cell.backgroundColor = UIColor(red: 52/255, green: 138/255, blue: 169/255, alpha: 1.0)
return cell
}
我还有一项功能可能会导致问题,但我对此表示怀疑:
HeightForRowAtIndexPath
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if newslists[indexPath.section][indexPath.row].imageURL != "None"{
println("Expanding cell for \(indexPath.section) \(indexPath.row)")
return 190.0
}
return 70.0
}
我不确定你为什么在这两种方法中都有一个双 for 循环。为每个可能的 indexPath 调用,因此您可以使用 indexPath 部分和行获取适当的数据。
您可以试试这个代码,我看不出有什么理由不能用。
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("NewsCell", forIndexPath: indexPath) as! UITableViewCell
cell.imageView?.image = nil
if newslists[indexPath.section][indexPath.row].imageURL != "None"{
let urlString = newslists[indexPath.section][indexPath.row].imageURL
let imgURL = NSURL(string: urlString)
cell.imageView?.image = UIImage(named: "first") // placeholder
if let img = imageCache[urlString] {
cell.imageView?.image = img
println("loaded from cache")
}
else {
...
}
}
return cell
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
if newslists[indexPath.section][indexPath.row].imageURL != "None"{
println("Expanding cell for \(i) \(j)")
return 190.0
}
return 70.0
}
我们需要做的就是使用prepareForReuse()
函数。正如 this 中篇文章中所讨论的,此函数在单元格重用之前调用,让您取消当前请求并执行重置。
override func prepareForReuse() {
super.prepareForReuse()
imageView.image = nil
}