Ios didSelectRowAt未按预期工作

Ios didSelectRowAt未按预期工作,ios,swift,uitableview,Ios,Swift,Uitableview,我在为手机打勾时遇到问题。我在牢房里贴了一张支票标签。 当用户点击单元格时,标签显示● 当用户再次点击该单元格时,它应该会显示出来○. 但是,当我点击一个单元格(例如索引路径0,10)时,将同时显示0,10和0,5●. 为什么会发生这种情况?感谢您的帮助 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { if isEditingSetlist{ if let ce

我在为手机打勾时遇到问题。我在牢房里贴了一张支票标签。 当用户点击单元格时,标签显示● 当用户再次点击该单元格时,它应该会显示出来○. 但是,当我点击一个单元格(例如索引路径0,10)时,将同时显示0,10和0,5●. 为什么会发生这种情况?感谢您的帮助

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if isEditingSetlist{
        if let cell = booklistDetailTableView.cellForRow(at: indexPath) as? BooklistTableViewCell {
            if cell.checkLabel.text == "●"{
                cell.checkLabel.text = "○"
            }else{
                cell.checkLabel.text = "●"
            }
        }
        selectedRows.append(indexPath.row)
    }
}

在didSelect方法中,只需从数组中追加和删除索引路径。。。如果该索引已经存在。。。从数组中删除该值。。。否则附加。。然后重新加载tableView

在cellForRow方法中,检查selectedRows数组put
中是否存在indexPath●"否则放入
“○“
to
cell.checkLabel.text

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
       if selectedRows.contains(indexPath.row) {
    //remove it from array
if let index = selectedRows.index(where: { $0 == indexPath.row }) {
      selectedRows.remove(at: index)

    }
    }else {
            selectedRows.append(indexPath.row)
        }
    tableView.reloadData()
    }

单元格被重用。例如,最有效的解决方案是在数据模型中添加
isSelected
属性

struct Model {

   var isSelected = false

   // other properties
}
cellForRowAt
中相应地设置复选标记(
dataSource
表示数据源数组)

didSelectRow
中,切换
isSelected
并重新加载行(调用
cellForRowAt


并且忘记
selectedRows
。如果可以插入、删除或移动单元格,则额外的数组会变得很烦人。

UITableViewCell是一种引用类型。因此,当您在单元格内更改UILabel值时,它将应用于所有其他引用。为避免此问题,可以使用数组

请尝试以下代码示例:

ViewController.swift文件

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
    @IBOutlet weak var tavleView: UITableView!
    var items: [Book]?

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if let item = items?[indexPath.row] {
            item.isCheck = !item.isCheck
            tableView.reloadRows(at: [indexPath], with: .none)
        }
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items?.count ?? 0
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? BooklistTableViewCell {
            if let item = items?[indexPath.row] {
                if !item.isCheck {
                    cell.checkLabel.text = "○ \(item.isCheck) \(indexPath.row)"
                }else{
                    cell.checkLabel.text = "● \(item.isCheck) \(indexPath.row)"
                }
            }
            return cell
        }
        return UITableViewCell()
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        items = (0..<20).map({ _ in Book(false) })
        tavleView.delegate = self
        tavleView.dataSource = self
        tavleView.reloadData()
    }
}
import UIKit

class BooklistTableViewCell: UITableViewCell {
    @IBOutlet weak var checkLabel: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}
import Foundation

class Book {
    var isCheck = false

    init(_ isCheck: Bool) {
        self.isCheck = isCheck
    }
}
Book.swift文件

import UIKit

class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource{
    @IBOutlet weak var tavleView: UITableView!
    var items: [Book]?

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if let item = items?[indexPath.row] {
            item.isCheck = !item.isCheck
            tableView.reloadRows(at: [indexPath], with: .none)
        }
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return items?.count ?? 0
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as? BooklistTableViewCell {
            if let item = items?[indexPath.row] {
                if !item.isCheck {
                    cell.checkLabel.text = "○ \(item.isCheck) \(indexPath.row)"
                }else{
                    cell.checkLabel.text = "● \(item.isCheck) \(indexPath.row)"
                }
            }
            return cell
        }
        return UITableViewCell()
    }


    override func viewDidLoad() {
        super.viewDidLoad()
        items = (0..<20).map({ _ in Book(false) })
        tavleView.delegate = self
        tavleView.dataSource = self
        tavleView.reloadData()
    }
}
import UIKit

class BooklistTableViewCell: UITableViewCell {
    @IBOutlet weak var checkLabel: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}
import Foundation

class Book {
    var isCheck = false

    init(_ isCheck: Bool) {
        self.isCheck = isCheck
    }
}

您还可以更改
willDisplayCell
中的复选标记。这是在单元格呈现之前更改其外观的理想位置。从文档:

表视图在使用单元格绘制行之前将此消息发送给其委托,从而允许委托在显示单元格对象之前自定义单元格对象。此方法使委托有机会覆盖表视图先前设置的基于状态的属性,如选择和背景色。委托返回后,“表格视图”仅设置alpha和frame属性,然后仅设置行滑入或滑出时的动画

因此,对于您的情况,可能是这样的:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
     if cell.checkLabel.text == "●" {
       cell.checkLabel.text = "○"
     } else {
        cell.checkLabel.text = "●"
     }
 }

单元格将被重复使用,因此它们会随机显示。由于您正在跟踪数组中的选定行,因此应该相应地修改cellForRow方法。请尝试改为在
willDisplayCell
中设置复选标记。在追加indexpath后重新加载tableview…并相应地修改cellForRow