didSelectRowAt无法正常工作

问题描述 投票:0回答:3

我无法在一个单元格上打上勾号。我已经在单元格中放置了一个检查标签。当用户点击该单元格时,标签将显示●,而当用户再次点击该单元格时,标签将显示○。但是,当我点击一个单元格(例如索引路径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)
    }
}
ios swift uitableview
3个回答
2
投票

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

struct Model {

   var isSelected = false

   // other properties
}

cellForRowAt中相应地设置选中标记(dataSource代表数据源数组)

let item = dataSource[indexPath.row]
cell.checkLabel.text = item.isSelected ? "●" : "○"

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

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    if isEditingSetlist{
        dataSource[indexPath.row].isSelected.toggle()
        tableView.reloadRows(at: [indexPath], with: .automatic)
    }
}

忘记selectedRows。如果可以插入,删除或移动单元格,则多余的数组将变得很烦人。


0
投票

在didSelect方法中,仅追加并从数组中删除索引路径...如果该indexPath已经存在...从数组中删除索引路径...否则添加..然后重新加载tableView

并且在cellForRow方法中,检查selectedRows数组中是否存在indexPath,否则将"●"放入"○"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()
    }

0
投票

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()
    }
}

BooklistTableViewCell.swift文件

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)
    }
}

Book.swift文件

import Foundation

class Book {
    var isCheck = false

    init(_ isCheck: Bool) {
        self.isCheck = isCheck
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.