在TableView中以编程方式取消选择多行

时间:2019-11-02 10:12:08

标签: swift uitableview

我有一个tableView,当选择多于2行时,有取消选择行的问题。我有此错误:致命错误:索引超出范围。应用崩溃了。 当选择一行时,我需要将所选元素添加到另一个数组“ selectedTableRows”中,而取消选择某行时,我必须将其从“ selectedTableRows”数组中删除。

这是我的代码: 导入UIKit

ViewController类:UIViewController {

let myTV = UITableView()
var myNavBar: UINavigationBar!
var selectItem: UIButton!
var deselectItem: UIButton!
var deleteItem: UIButton!
var buttonsContainer: UIStackView!
var arrayNumbers = [3, 42, 56, 55, 73, 89, 24, 51, 64]
var selectedTableRows: [Int] = []

override func viewDidLoad() {
    super.viewDidLoad()
    let margins = self.view.layoutMarginsGuide
    myNavBar = UINavigationBar()
    myNavBar.barStyle = .black
    myNavBar.translatesAutoresizingMaskIntoConstraints = false

    let myNavTitle = UINavigationItem(title: "Home")

    myNavBar.setItems([myNavTitle], animated: true)

    self.view.addSubview(myNavBar)

    myNavBar.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
    myNavBar.topAnchor.constraint(equalTo: margins.topAnchor, constant: 10).isActive = true
    myNavBar.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
    showContent()
    print("SelectedTableRows has \(selectedTableRows.count) elements.")


}

func showContent() {

    if arrayNumbers.count > 0 {
        self.view.addSubview(myTV)
        myTV.backgroundColor = .clear
        myTV.separatorStyle = .none
        myTV.dataSource = self
        myTV.delegate = self
        myTV.allowsMultipleSelection = true
        myTV.register(UITableViewCell.self, forCellReuseIdentifier: "myCell")
        myTV.reloadData()
        myTV.translatesAutoresizingMaskIntoConstraints = false

        selectItem = UIButton(type: .custom)
        selectItem.backgroundColor = .green
        selectItem.frame.size = CGSize(width: 90, height: 90)
        selectItem.setTitleColor(.white, for: .normal)
        selectItem.setTitle("Select all.", for: .normal)
        selectItem.setTitle("Select all! Oscured.", for: .disabled)
        selectItem.isEnabled = true
        selectItem.addTarget(self, action: #selector(ViewController.selectItemAction(_:)), for: .touchUpInside)
        selectItem.layer.cornerRadius = selectItem.frame.width / 2
        selectItem.layer.masksToBounds = true
        selectItem.translatesAutoresizingMaskIntoConstraints = false

        deselectItem = UIButton(type: .custom)
        deselectItem.frame.size = CGSize(width: 90, height: 90)
        deselectItem.backgroundColor = .yellow
        deselectItem.setTitleColor(.black, for: .normal)
        deselectItem.setTitle("Deselect all!", for: .normal)
        deselectItem.setTitleColor(.black, for: .disabled)
        deselectItem.setTitle("Deselect all! Oscured", for: .disabled)
        deselectItem.isEnabled = false
        deselectItem.layer.cornerRadius = deselectItem.frame.width / 2
        deselectItem.layer.masksToBounds = true
        deselectItem.translatesAutoresizingMaskIntoConstraints = false


        deleteItem = UIButton(type: .custom)
        deleteItem.frame.size = CGSize(width: 90, height: 90)
        deleteItem.backgroundColor = .red
        deleteItem.setTitleColor(.white, for: .normal)
        deleteItem.setTitle("Delete items!", for: .normal)
        deleteItem.setTitleColor(.white, for: .disabled)
        deleteItem.setTitle("Delete items! Oscured.", for: .disabled)
        deleteItem.isEnabled = false
        deleteItem.layer.cornerRadius = deleteItem.frame.width / 2
        deleteItem.layer.masksToBounds = true
        deleteItem.translatesAutoresizingMaskIntoConstraints = false

        buttonsContainer = UIStackView(arrangedSubviews: [selectItem, deselectItem, deleteItem])
        buttonsContainer.frame.size = CGSize(width: self.view.frame.width, height: 100)
        buttonsContainer.axis = .horizontal
        buttonsContainer.alignment = .fill
        buttonsContainer.distribution = .fillEqually
        buttonsContainer.spacing = 100
        buttonsContainer.translatesAutoresizingMaskIntoConstraints = false

        self.view.addSubview(buttonsContainer)


        myTV.leadingAnchor.constraint(equalTo: self.view.leadingAnchor).isActive = true
        myTV.topAnchor.constraint(equalTo: myNavBar.bottomAnchor).isActive = true
        myTV.trailingAnchor.constraint(equalTo: self.view.trailingAnchor).isActive = true
        myTV.bottomAnchor.constraint(equalTo: buttonsContainer.topAnchor).isActive = true

        buttonsContainer.leadingAnchor.constraint(equalTo: myTV.leadingAnchor).isActive = true
        buttonsContainer.trailingAnchor.constraint(equalTo: myTV.trailingAnchor).isActive = true
        buttonsContainer.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
        } else {
        let emptyLabel = UILabel()
        emptyLabel.frame.size = CGSize(width: 150, height: 42)
        emptyLabel.backgroundColor = .white
        emptyLabel.textColor = .black
        emptyLabel.textAlignment = .center
        emptyLabel.numberOfLines = 0
        emptyLabel.adjustsFontSizeToFitWidth = true
        emptyLabel.text = NSLocalizedString("You have any rss in your list. Please press ADD RSS button to add one!", comment: "")
        emptyLabel.layer.cornerRadius = 5
        emptyLabel.layer.masksToBounds = true
        emptyLabel.translatesAutoresizingMaskIntoConstraints = false

        self.view.addSubview(emptyLabel)

        emptyLabel.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
        emptyLabel.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
    }


}


@objc func selectItemAction(_ sender: UIButton) {
    print("Select all button pressed.")
    print("SelectedTableRows has \(selectedTableRows.count) elements")

    for x in 0..<arrayNumbers.count {
        if myTV.cellForRow(at: IndexPath(item: x, section: 0))?.isSelected == false {
            myTV.selectRow(at: IndexPath(item: x, section: 0), animated: true, scrollPosition: .none)
            print("\(arrayNumbers[x]) was selected.")
        }
    }
    print("SelectedTableRows has \(selectedTableRows.count) elements")
}

@objc func deselectItemAction(_ sender: UIButton) {

    print("DeselectItemActionbutton pressed.")
    print("SelectedTableRows has \(selectedTableRows.count) elements")

    for x in myTV.indexPathsForSelectedRows! {
        myTV.deselectRow(at: [x.item], animated: true)
    }
    selectedTableRows.removeAll()
    print("SelectedTableRows has \(selectedTableRows.count) elements")
}

@objc func deleteItemAction(_ sender: UIButton) {
    print("DeleteItemAction button pressed.")
    print("SelectedTableRows has \(selectedTableRows.count) elements")

    for x in myTV.indexPathsForSelectedRows! {
        print(" \(x.item)viewed.")
        arrayNumbers.remove(at: x.item)
        myTV.reloadData()
    }

    selectedTableRows.removeAll()
    print("SelectedTableRows has \(selectedTableRows.count) elements")
}

}

扩展ViewController:UITableViewDataSource {

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

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = myTV.dequeueReusableCell(withIdentifier: "myCell", for: indexPath)
    cell.textLabel?.text = "\(arrayNumbers[indexPath.row])"
    return cell
}

}

扩展ViewController:UITableViewDelegate {

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    print("You have selected \(arrayNumbers[indexPath.row]).")
    selectedTableRows.append(arrayNumbers[indexPath.item])
    print("\(selectedTableRows.last!) was added to selectedTableRows.")
    print("SelectedTableRows has \(selectedTableRows.count) elements.")
    if selectedTableRows.count > 0 {
        deselectItem.isEnabled = true
        deleteItem.isEnabled = true
    }
    if selectedTableRows.count == arrayNumbers.count {
        selectItem.isEnabled = false
    }
    print("SelectedTableRows has \(selectedTableRows.count) elements")
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    print("\(arrayNumbers[indexPath.item]) was deselected.")
    let itemToDeselect = arrayNumbers[indexPath.item]
    print("SelectedTableRows has \(selectedTableRows.count) elements.")

    for x in 0..<selectedTableRows.count {
        if selectedTableRows[x] == itemToDeselect {
            selectedTableRows.remove(at: x)
        }
    }
    print("SelectedTableRows has \(selectedTableRows.count) elements")
    if selectedTableRows.count == 0 {
        deselectItem.isEnabled = false
        deleteItem.isEnabled = false
    }

    if selectedTableRows.count < arrayNumbers.count {
        selectItem.isEnabled = true
    }
}

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

    let deviceModel = UIDevice.current.model

    switch deviceModel {
    case "iPad":
        return myTV.frame.height / 10
    default:
        return myTV.frame.height / 5
    }
}

}

我该如何解决? 非常感谢你!

1 个答案:

答案 0 :(得分:0)

如果我是你,我将像这样构造我的数组

struct arrayData {
    var number : Int
    var isSelected : Bool
}

var arrayNumbers = [arrayData]()

,然后像这样添加数据并相应地更新 在取消选择操作中

arrayNumbers = [arrayData(number: 3, isSelected: false),
                    arrayData(number: 42, isSelected: false),
                    arrayData(number: 56, isSelected: false),
                    arrayData(number: 55, isSelected: false),
                    arrayData(number: 73, isSelected: false),
                    arrayData(number: 89, isSelected: false),
                    arrayData(number: 24, isSelected: false),
                    arrayData(number: 51, isSelected: false),
                    arrayData(number: 64, isSelected: false)]