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

non*_*tic 2 uitableview ios swift

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

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

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

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..<50 {
      numbers.append(i)
    }
  }

  override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> 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)
    }

  }
Run Code Online (Sandbox Code Playgroud)

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

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

编辑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..<50 {
      let listItem = ListItem(name: "row \(i)")
      listItems.append(listItem)
    }
  }


  // MARK: - Table view data source

  override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> 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)
    }
  }

}
Run Code Online (Sandbox Code Playgroud)

编辑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..<50 {
      let listItem = ListItem(name: "row \(i)")
      listItems.append(listItem)
    }
  }


  // MARK: - Table view data source

  override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> 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
  }

}
Run Code Online (Sandbox Code Playgroud)

mat*_*att 5

问题是单元格在其他行中重用.当他们是,cellForRowAtIndexPath再次被召唤.但是,如果是,则不提供有关该行图像的信息.

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