添加到UITableViewCell的图像在滚动时显示在错误的行中

我在选择它时将一个图像添加到表视图行(实际上,我似乎将它添加到行的单元格中)(并在再次选择时删除)。 表视图由原型单元组成。

这可以工作但是当我滚动并回到我之前选择的行时,图像将在另一行。 此外,图像也出现在其他行中。

我的猜测是因为滚动时重复使用了单元格。 这是一个小示例项目的代码:

import UIKit class MyTableViewController: UITableViewController { // Using integers for simplicity, should work with strings, too. var numbers = [Int]() override func viewDidLoad() { super.viewDidLoad() for i in 0.. UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("TestCell", forIndexPath: indexPath) cell.textLabel?.text = "\(numbers[indexPath.row] + 1)" return cell } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return numbers.count } override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { let cell = tableView.cellForRowAtIndexPath(indexPath)! if let myImage = curCell.viewWithTag(10) as? MyImage { myImage.removeFromSuperview() } else { let myImage = myImage() myImage.tag = 10 cell.addSubview(myImage) } } 

我需要让图像保持在正确的行中,同样在返回此视图控制器时也是如此。 解决这个问题的正确方法是什么? 任何建议非常感谢!

编辑 :我试图实现亚特的答案,但我似乎缺少一些东西,因为问题仍然是相同的。

编辑2 :更新,现在按预期工作。

 import UIKit class ListItem { var name: String! var showsImage = false init(name: String) { self.name = name } } class MyTableViewController: UITableViewController { var listItems = [ListItem]() override func viewDidLoad() { super.viewDidLoad() for i in 0.. UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("TestCell", forIndexPath: indexPath) cell.textLabel?.text = "\(listItems[indexPath.row].name)" if listItems[indexPath.row].showsImage { let myImage = myImage myImage.tag = 10 cell.addSubview(myImage) } else { if let myImage = cell.viewWithTag(10) as? myImage { myImage.removeFromSuperview() listItems[indexPath.row].showsImage = false } return cell } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return listItems.count } override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { let cell = tableView.cellForRowAtIndexPath(indexPath)! if let myImage = cell.viewWithTag(10) as? myImage { myImage.removeFromSuperview() listItems[indexPath.row].showsImage = false } else { listItems[indexPath.row].showsImage = true tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: .None) } } } 

编辑3 :正如亚光所建议的,这里是上面代码的替代解决方案,其中包含UITableViewCell的子类,而不是使用图像的标记。

 import UIKit class MyTableViewCell: UITableViewCell { var myImage = MyImage() override init(style: UITableViewCellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) myImage.hidden = true addSubview(myImage) } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } class ListItem { var name: String! var showsImage = false init(name: String) { self.name = name } } class MyTableViewController: UITableViewController { var listItems = [ListItem]() override func viewDidLoad() { super.viewDidLoad() for i in 0.. Int { return listItems.count } override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = MyTableViewCell(style: .Default, reuseIdentifier: "TestCell") cell.textLabel?.text = "\(listItems[indexPath.row].name)" cell.myImage.hidden = !(listItems[indexPath.row].showsImage) return cell } override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { let cell = tableView.cellForRowAtIndexPath(indexPath) as! MyTableViewCell listItems[indexPath.row].showsImage = cell.myImage.hidden cell.myImage.hidden = !cell.myImage.hidden } } 

问题是单元格在其他行中重用。 如果是,则再次调用cellForRowAtIndexPath 。 但是当它出现时,您没有提供有关该行图像的信息。

解决方案:修复您的模型 (即您在cellForRowAtIndexPath查询的信息),以便它知道图像。 在didSelect ,不要直接修改单元格。 而是修改模型并重新加载单元格。