Удаление пользовательского представления из UITableView - PullRequest
0 голосов
/ 05 июля 2018

Я проведу пальцем влево, чтобы удалить ячейку, являющуюся пользовательским представлением в Swift 3.

Ячейка:

class CustomTableCell: SwipeTableViewCell
{
    public var atest = UILabel();
    public var btest = UILabel();

    var animator: Any?

    override init(style: UITableViewCellStyle, reuseIdentifier: String!)
    {
        super.init(style: style, reuseIdentifier: reuseIdentifier);

        let height = 140;

        atest = UILabel(frame: CGRect(x: 20 + (activityWidth / 2), y: 72, width: (activityWidth / 2) - 10, height: 30));

        btest = UILabel(frame: CGRect(x: 20 + (activityWidth / 2), y: 102, width: (activityWidth / 2) - 10, height: 30));

        self.contentView.addSubview(atest);
        self.contentView.addSubview(btest);
    }

Тогда в моем контроллере представления таблицы:

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

    cell.atest.text = "text from an array at indexpath.row";
    cell.btest.text = "another different text from an array";

    return cell;
}

Удаление в контроллере табличного представления происходит здесь:

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]?
{
    let delete = SwipeAction(style: .destructive, title: "Delete")
    {
        action, indexPath in
        print("delete button tapped");

        // self.table.deleteRows(at: [indexPath], with: .none);

        // database is a string index array
        self.database.remove(at: indexPath.row);

        if (self.database.count == 0)
        {
            self.noText.isHidden = false;
            self.footer.isHidden = false;

            self.table.tableFooterView = self.footer;
        }

        // self.table.setNeedsDisplay();
    }

    delete.backgroundColor = UIColor.red;

    return [delete];

Я делаю удаление, проводя пальцем влево, и оно удаляет все правильно. У меня проблема в том, что удаление делает все ячейки табличного представления под сгибом такими же, как последняя видимая ячейка.

Как мне это исправить? Я тоже использую пользовательский вид ячеек.

Примером является то, что у меня есть 6 строк, а верхние 4 видимы. Удаление первого ряда делает 4-й и 5-й ряды одинаковыми. Как и в последнем видимом ряду, также становится первым невидимым рядом. PrepareForReuse, вероятно, не работает правильно.

Удаление работает и идет от 6 строк до 5, но пример ниже.

 UITableView
 First row label         A
 Second row label        B
 Third row label         C
 Fourth row label        D (last visible row)
 Fifth row label         E (first non visible row)
 Sixth row label         F

Удаление первой строки смахиванием создает этот новый UITableView:

 UITableView
 Second row label        B
 Third row label         C
 Fourth row label        D
 Fourth row label        D (last visible row)
 Fifth row label         E (first non visible row)

Многоразовые ячейки работают неправильно.

Я не использую awakeFromNib, а просто обновил до swift 4.1.

Ответы [ 2 ]

0 голосов
/ 12 июля 2018

Проблема в том, как ваши клетки используются повторно. Добавьте эту строку кода в класс ячейки вашей таблицы:

  override func prepareForReuse() {
    super.prepareForReuse()

        atest.text = nil
        btest.text = nil
  }
0 голосов
/ 05 июля 2018

В TableView пользовательских ячейках, если вы добавляете views из storyboard или XIB, тогда они удаляются при прокрутке, но если вы добавляете views программно, то вам нужно удалить представление из tableViewCell:

Либо используйте следующий код в cellForRow:

for label in cell.subviews {
    if let mylabel = label as? UILabel {
        mylabel.removeFromSuperview()
    }
}

или вы можете использовать этот код customCellClass в методе prepareForReuse:

class myCustomCell: UITableViewCell {

    override func prepareForReuse() {
        super.prepareForReuse()
        for view in self.subviews {
            view.removeFromSuperview()
        }
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

}

Приведенный выше код удалит все подпредставления из ячейки.

Проверьте ниже ссылки для получения дополнительных ответов:

EDIT

Я попробовал приведенный ниже код с функциональностью Array и swipeDelete в tableView:

class ViewController: UIViewController {

    @IBOutlet weak var sampleTableView: UITableView!

    var nameArray = ["Snoop", "Sarah", "Fido", "Mark", "Jill", "Parague", "London", "Barcelona", "Italy", "France", "Eiffiel", "Tower", "Paris", "Europe", "Amsterdam", "Zurich", "Germany", "Munich", "Milan", "Venice", "Switzerland", "Brussels"]

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
}

extension ViewController: UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return nameArray.count
    }

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

        cell.textLabel?.text = nameArray[indexPath.row] + " - " + String(describing: indexPath.row)

        return cell
    }

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        return true
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if (editingStyle == UITableViewCellEditingStyle.delete) {
            // handle delete (by removing the data from your array and updating the tableview)
            tableView.beginUpdates()
            nameArray.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .automatic)
            tableView.endUpdates()
        }
    }
}

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

РЕДАКТИРОВАТЬ Используя SwipwCellKit:

Использовал ваш код с SwipeCellKit:

Мой ViewController:

class ViewController: UIViewController {

    @IBOutlet weak var sampleTableView: UITableView!

    var nameArray = ["Snoop", "Sarah", "Fido", "Mark", "Jill", "Parague", "London", "Barcelona", "Italy", "France", "Eiffiel", "Tower", "Paris", "Europe", "Amsterdam", "Zurich", "Germany", "Munich", "Milan", "Venice", "Switzerland", "Brussels"]

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
}

extension ViewController : UITableViewDataSource, UITableViewDelegate, SwipeTableViewCellDelegate {

    func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 72
    }

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

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

        cell.delegate = self

        cell.atest.text = nameArray[indexPath.row] + " - " + String(describing: indexPath.row)
        cell.btest.text = "another different text from an array";

        return cell;
    }

    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]?
    {
        let delete = SwipeAction(style: .destructive, title: "Delete")
        {
            action, indexPath in
            print("delete button tapped")

            self.nameArray.remove(at: indexPath.row)

            self.sampleTableView.deleteRows(at: [indexPath], with: .none)
        }

        delete.backgroundColor = UIColor.red;

        return [delete];
    }
}

Мой CustomTableViewCell:

class CustomTableCell: SwipeTableViewCell {

    public var atest = UILabel()
    public var btest = UILabel()

    var animator: Any?

    override func awakeFromNib() {
        atest = UILabel(frame: CGRect(x: 20 , y: 2, width: 200, height: 30));

        btest = UILabel(frame: CGRect(x: 20 , y: 32, width: 200, height: 30));

        self.contentView.addSubview(atest);
        self.contentView.addSubview(btest);
    }

}

Работает так же, как и при первом редактировании.

EDIT

CustomTableViewCell с использованием init:

class CustomTableViewCell: SwipeTableViewCell {

    public var atest = UILabel();
    public var btest = UILabel();

    var animator: Any?

    override init(style: UITableViewCellStyle, reuseIdentifier: String!)
    {
        super.init(style: style, reuseIdentifier: reuseIdentifier)


        atest = UILabel(frame: CGRect(x: 20 , y: 2, width: 100, height: 30))

        btest = UILabel(frame: CGRect(x: 20 , y: 32, width: 100, height: 30))

        self.contentView.addSubview(atest)
        self.contentView.addSubview(btest)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        fatalError("init(coder:) has not been implemented")
    }
}

изменение cellForRow:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = CustomTableViewCell.init(style: .default, reuseIdentifier: "reuseIdentifier")

    cell.delegate = self

    cell.atest.text = nameArray[indexPath.row] + " - " + String(describing: indexPath.row)
    cell.btest.text = "another different text from an array";

    return cell;
}

все еще работает так же, как и выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...