我有一个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
}
}
}
我该如何解决? 非常感谢你!
答案 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)]