didSelectRowAt не работает, как предполагалось - PullRequest
0 голосов
/ 24 февраля 2020

У меня проблемы с установкой галочки для ячейки. Я поместил контрольную метку в камеру. Когда пользователь касается ячейки, метка отображается ●, а когда пользователь снова касается ячейки, она должна отображать ○. Однако, когда я нажимаю на ячейку, например, индексный путь 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)
    }
}

Ответы [ 4 ]

6 голосов
/ 24 февраля 2020

Клетки используются повторно. Наиболее эффективным решением является добавление свойства 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. Дополнительные массивы становятся раздражающими, если ячейки могут быть вставлены, удалены или перемещены.

3 голосов
/ 24 февраля 2020

В методе didSelect просто добавьте и удалите путь индекса из массива ... если этот indexPath уже существует ... удалите его из массива ... в противном случае добавьте .. затем перезагрузите tableView

И в вашем методе cellForRow проверьте, существует ли этот indexPath в массиве selectedRows, установите "●", в противном случае установите "○" в 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()
    }
1 голос
/ 24 февраля 2020

Вы также можете изменить галочку в willDisplayCell. Это идеальное место для изменения внешнего вида ячейки непосредственно перед ее отображением. Из документов:

Представление таблицы отправляет это сообщение своему делегату непосредственно перед тем, как использовать ячейку для рисования строки, что позволяет делегату настроить объект ячейки перед его отображением. Этот метод дает делегату возможность переопределять основанные на состоянии свойства, установленные ранее табличным представлением, такие как выделение и цвет фона. После возврата делегата табличное представление устанавливает только свойства альфа-канала и фрейма, а затем только при анимации строк по мере их скольжения внутрь или наружу.

Так что для вашего случая это может быть что-то вроде:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
     if cell.checkLabel.text == "●" {
       cell.checkLabel.text = "○"
     } else {
        cell.checkLabel.text = "●"
     }
 }
0 голосов
/ 24 февраля 2020

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
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...