首页 > 解决方案 > UITableViewCell 多选圈(编辑控件)随机出现

问题描述

我创建了一个带有 UITableView 作为子视图的 ViewController。

import UIKit


class ViewController: UIViewController {

    private var tableDataSource = [
        "Lorem Ipsum is simply du.",
        "It is a long established .",
        "Lorem Ipsum come",
        "All the Lorem .",
        "The standard ch.",
        "The generated.",
        "Various versions."
                           ]


    private var isReorderingEnabled = false
    private var isDeleteEnabled = false

    @IBOutlet private var reorderCellsBarButton: UIBarButtonItem!
    @IBOutlet private var selectCellsBarButton: UIBarButtonItem! {
        didSet {
            selectCellsBarButton.tag = ButtonTags.Select
        }
    }
    @IBOutlet private var deleteCellsBarButton: UIBarButtonItem! {
        didSet {
            deleteCellsBarButton.tag = ButtonTags.Delete
        }
    }
    @IBOutlet weak private var tableView: UITableView! {
        didSet {
            tableView.dataSource = self
            tableView.delegate = self
            tableView.allowsMultipleSelectionDuringEditing = false
            tableView.rowHeight = UITableViewAutomaticDimension
            tableView.estimatedRowHeight = 300
        }
    }

}


extension ViewController {

    private struct ButtonTags {
        static let Delete = 2
        static let Select = 1
    }

    private struct LocalizedStrings {
        static let EnableReorderingText = "Reorder"
        static let DisableReorderingText = "Done"
        static let EnableSelectionText = "Select"
        static let ConfirmDeletionText = "Delete"
        static let DisableDeletionText = "Cancel"
    }

}



extension ViewController {
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        setDeleteBarButton(hidden: true, animated: false)
    }
}



// IBActions
extension ViewController {

    @IBAction private func reorderCells(_ sender: UIBarButtonItem) {
        isReorderingEnabled = !tableView.isEditing
        setSelectBarButton(hidden: isReorderingEnabled)
        sender.title = isReorderingEnabled ? LocalizedStrings.DisableReorderingText : LocalizedStrings.EnableReorderingText
        tableView.setEditing(isReorderingEnabled, animated: true)
        tableView.reloadData()
    }

    @IBAction private func deleteCells(_ sender: UIBarButtonItem) {
        isDeleteEnabled = !tableView.isEditing
        setDeleteBarButton(hidden: !isDeleteEnabled)
        selectCellsBarButton.title = isDeleteEnabled ? LocalizedStrings.DisableDeletionText : LocalizedStrings.EnableSelectionText
        if sender.tag == ButtonTags.Delete {
            deleteSelectedRows()
        }
        tableView.allowsMultipleSelectionDuringEditing = isDeleteEnabled
        tableView.setEditing(isDeleteEnabled, animated: true)
        tableView.reloadData()
    }

}

// Custom Helper methods
extension ViewController {

    private func setDeleteBarButton(hidden: Bool, animated: Bool = true) {
        navigationItem.setRightBarButtonItems([(hidden ? reorderCellsBarButton : deleteCellsBarButton)], animated: animated)
    }

    private func setSelectBarButton(hidden: Bool, animated: Bool = true) {
        self.navigationItem.setLeftBarButton((hidden ? nil : selectCellsBarButton), animated: animated)
    }

    private func deleteSelectedRows() {
        guard let selectedRows = tableView.indexPathsForSelectedRows else { return }
        let indexes = selectedRows.map { $0.row }
        tableDataSource.remove(indexes: indexes)
        tableView.deleteRows(at: selectedRows, with: .fade)
    }

}


extension ViewController: UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

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

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let customCell = tableView.dequeueReusableCell(withIdentifier: CustomTableViewCell.identifier, for: indexPath) as! CustomTableViewCell
        customCell.setup(content: tableDataSource[indexPath.row], for : indexPath.row)
        return customCell
    }

}


// pragma - To Select/Edit/Move TableView Cells
extension ViewController: UITableViewDelegate {

    func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
        tableDataSource.move(from: sourceIndexPath.row, to: destinationIndexPath.row)
        let reloadingIndexPaths = IndexPath.createForNumbers(from: sourceIndexPath.row, to: destinationIndexPath.row)
        DispatchQueue.main.async {
            tableView.reloadRows(at: reloadingIndexPaths, with: .none)
        }
    }

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            tableDataSource.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .none)
        }
    }

}

// pragma - Settings for Edit/Move TableViewCell
extension ViewController {

    func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
        print("Edit- \(tableView.isEditing)")
        return tableView.isEditing
    }

    func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
        print("Move- \(isReorderingEnabled)")
        return isReorderingEnabled
    }

    func tableView(_ tableView: UITableView, editingStyleForRowAt indexPath: IndexPath) -> UITableViewCellEditingStyle {
        print("Style- None")
        return .none
    }

    func tableView(_ tableView: UITableView, shouldIndentWhileEditingRowAt indexPath: IndexPath) -> Bool {
        print("indent- \(isDeleteEnabled)")
        return isDeleteEnabled
    }

}

在此,我制作了三个条形按钮,一个用于重新排序,另外两个用于删除和取消。因此,对于删除,我提供了选择多行的能力。

But the problem is, when Reordering selected, the checkbox is still appearing(Not clickable though). And sometimes when Deletion selected, checkbox doesn't appear.

模拟器快照

无法理解这种荒谬的行为。这是 XCode 的错误吗?请帮忙。

添加内容:

CustomTableViewCell 类:

import UIKit

class CustomTableViewCell: UITableViewCell {

    static let identifier = "customCellIdentifier"

    @IBOutlet weak private var titleLabel: UILabel!
    @IBOutlet weak private var backgroundImageView: UIImageView!


    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        let selectionView = UIView()
        selectionView.backgroundColor = UIColor.clear
        selectedBackgroundView = selectionView
    }

}



extension CustomTableViewCell {

    func setup(content: String, for rowNumber: Int) {
        titleLabel.text = content
        let backgroundImageName = rowNumber % 2 == 0 ? ImageAssetNames.BlueMatte : ImageAssetNames.GreenThreads
        backgroundView = UIImageView(image: UIImage(named: backgroundImageName))
    }

}

标签: iosswiftxcodeuitableviewswift3

解决方案


推荐阅读