Удалите ячейку / строку UITableView в UITableView с несколькими разделами, используя закрытие не работает - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть UITableView в UIViewController, который состоит из динамических нескольких разделов и динамических нескольких ячеек / строк в каждом разделе.

Я пытался использовать действия, замыкания, путь индекса.Etc

Я хочу нажать UIButton в пользовательском UITableViewCell и удалить / удалить строку и соответствующие данные.

В настоящее время, когда я пытаюсь это сделать, я могу удалить первую ячейку враздел, но затем, когда я пытаюсь удалить последний раздел, я получаю сбой, Индекс выходит за пределы.Кажется, что UIButton сохраняет старый indexPath.row

Я попытался reloadData () для таблицы, но мне не удалось успешно решить эту проблему.

Использование этого решения из SO ( Действие UIButton в ячейке табличного представления ):

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var myTableView: UITableView!

    var sections: [String] = []

    var items: [[String]] = []

    var things: [[String]] = []
    var things2: [[String]] = []

    override func viewDidLoad() {
        super.viewDidLoad()

        things = [["A","B","C","D"],["X","Y","Z"],["J","A","A","E","K"]]

        things2 = [["Q","W","E","R"], ["G","H","J"]]

        items.append(contentsOf: things)
        items.append(contentsOf: things2)


        let secs: Int = Int.random(in: 1...items.count)

        for num in 1...secs {

            if num == 1 {
                sections.append("My Stuff")
            } else {
                sections.append("Section \(num)")
            }


        }

    }

}

extension ViewController: UITableViewDelegate, UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return sections.count
    }

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

    func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return sections[section]
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MyCustomTableViewCell

        cell.theLabel?.text = items[indexPath.section][indexPath.row]

        if indexPath.section == 0 {
            cell.deleteButton.isHidden = false
            cell.editButton.isHidden = false

            cell.deleteButton.addAction {

                // This is broken, when the action is added in the closure. It persists the indexPath as it is, not changed even with a reloadData()

                self.items[indexPath.section].remove(at: indexPath.row)
                self.myTableView.deleteRows(at: [indexPath], with: .fade)


            }

            cell.editButton.addAction {
                print("I'm editing this row")
                cell.backgroundColor = UIColor.magenta
            }


        } else {
            cell.deleteButton.isHidden = true
            cell.editButton.isHidden = true
        }


        return cell
    }



}

// used from https://stackoverflow.com/questions/28894765/uibutton-action-in-table-view-cell/41374087

extension UIControl {
    func addAction(for controlEvents: UIControl.Event = .primaryActionTriggered, action: @escaping () -> ()) {
        let sleeve = ClosureSleeve(attachTo: self, closure: action)
        addTarget(sleeve, action: #selector(ClosureSleeve.invoke), for: controlEvents)
    }

}

class ClosureSleeve {
    let closure: () -> ()

    init(attachTo: AnyObject, closure: @escaping () -> ()) {
        self.closure = closure
        objc_setAssociatedObject(attachTo, "[\(arc4random())]", self,.OBJC_ASSOCIATION_RETAIN)
    }

    @objc func invoke() {
        closure()
    }
}

Проблема, связанная с использованием этого в нескольких разделах, заключается в том, что он сохраняет исходный indexPath и строку.

Пример:если секция 0 имеет два элемента (0,1), я удаляю секцию 0, элемент 0 - она ​​работает как положено.Затем, когда я нажимаю кнопку, чтобы удалить оставшуюся ячейку, которая была элементом 1 раздела 0 и должна была быть перезагружена в элемент 0 раздела 0. Это не удается, потому что закрытие все еще видит блок кода как элемент 1 раздела 0. Даже через reloadData() Закрытие все еще видит первоначальное назначение indexPath.section и indexPath.row

У кого-нибудь есть какие-нибудь идеи?

Я думаю, что это как-то связано с сохранением, но, честно говоря,Я рисую бланк.Я искал этот код в отладчике в течение дня или двух, и я расстроен и мне нужна помощь Йоды ...

...