[英]"Thread 1: Fatal error: Index out of range" from an array initialized with a length of zero/empty but it's definitely not empty when requested
So I currently have a tableView in a ViewController called GearComponentViewController
that has custom tableViewCells that have a UIStepper in them to control a quantity label and conforms to the custom protocol Stepper
.所以我目前在一个名为
GearComponentViewController
的 ViewController 中有一个 tableView ,它有一个自定义 tableViewCells ,其中有一个 UIStepper 来控制数量 label 并符合自定义协议Stepper
。
protocol Stepper {
func stepperWasPressed(didIncrease: Bool, namePassed: String, userindexPath: Int)
}
And here's the code for the GearComponentTableViewCell
:这是
GearComponentTableViewCell
的代码:
class GearComponentTableViewCell: UITableViewCell {
var mainVC = GearComponentViewController()
var tableViewCellPosition: Int! = nil
// Image
@IBOutlet weak var itemImage: UIImageView!
// Name
@IBOutlet weak var itemName: UILabel!
// Weight
@IBOutlet weak var itemWeight1: UILabel!
@IBOutlet weak var itemWeight2: UILabel!
// Quanity
@IBOutlet weak var itemQuanity: UILabel!
@IBAction func stepperPressed (_ sender: UIStepper!){
if (sender.value == 1) {
print("up and item: \(itemName.text!)");
sender.value = 0
mainVC.stepperWasPressed(didIncrease: true, namePassed: itemName.text!, userindexPath: tableViewCellPosition)
} else if (sender.value == -1) {
print("down and item: \(itemName.text!)");
sender.value = 0
mainVC.stepperWasPressed(didIncrease: false, namePassed: itemName.text!, userindexPath: tableViewCellPosition)
}
}
// Notes
@IBOutlet weak var itemNotes: UILabel!
} }
It detects if the user clicked on the plus button or the minus button on the stepper and calls the function from the protocol stepperWasPressed()
它检测用户是否单击了步进器上的加号按钮或减号按钮,并从协议
stepperWasPressed()
调用 function
Finally here's the code for the mainVC
referenced:最后是引用的
mainVC
的代码:
extension GearComponentViewController: Stepper {
func refreshTableViewCell() {
print("arrayPosition: \(arrayPosition)")
// gearTableView.reloadData()
}
func stepperWasPressed(didIncrease: Bool, namePassed: String, userindexPath: Int) {
if didIncrease {
arrayPosition = userindexPath
print("arrayPosition: \(arrayPosition)")
// itemArray[userindexPath].quanity += 1
print("userindexPath: \(userindexPath) -- namePassed: \(namePassed) -- didIncrease: \(didIncrease)")
print("increase selected")
refreshTableViewCell()
}else {
arrayPosition = userindexPath
print("arrayPosition: \(arrayPosition)")
// itemArray[userindexPath].quanity -= 1
print("userindexPath: \(userindexPath) -- namePassed: \(namePassed) -- didIncrease: \(didIncrease)")
print("decrease selected")
refreshTableViewCell()
}
}
}
When I try to do either itemArray[userindexPath].quanity += 1
or itemArray[userindexPath].quanity -= 1
I'm getting the error listed in the title, but to be even able to call that part of the function the count of my itemArray has to be greater than zero/empty because I'm being presented a cell with a stepper in it.当我尝试执行
itemArray[userindexPath].quanity += 1
或itemArray[userindexPath].quanity -= 1
时,我得到了标题中列出的错误,但甚至能够调用 function 的那部分计数我的 itemArray 必须大于零/空,因为我看到的是一个带有步进器的单元格。
Full GearComponentViewController:完整的 GearComponentViewController:
import UIKit
class GearComponentViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
var arrayPosition: Int = 0
// Data Sources
var itemArray: [GearItem] = []
var totalWeight1: Int = 0
var totalWeight2: Int = 0
var totalItems: Int = 0
// Weight Label Outlets
@IBOutlet weak var weight1LabelOutlet: UILabel!
@IBOutlet weak var weight2LabelOutlet: UILabel!
// Item Count Label Outlet
@IBOutlet weak var totalCountLabelOutlet: UILabel!
// TableView Outlet
@IBOutlet weak var gearTableView: UITableView!
// Bar Button Item
@IBAction func addItemPressed(_ sender: Any) {
presentAlert()
}
// View Did Load
override func viewDidLoad() {
super.viewDidLoad()
gearTableView.dataSource = self
gearTableView.delegate = self
print("Gear Component View Controller successfully loaded.")
updateUI()
// Do any additional setup after loading the view.
}
//MARK: - UI Updater
func updateUI() {
addTotalWeight()
addAllItems()
}
// Adding Total Weight
func addTotalWeight() {
var addedWeight1: Int = 0
var addedWeight2: Int = 0
for item in itemArray {
addedWeight1 += item.weight1 * item.quantity
addedWeight2 += item.weight2 * item.quantity
}
totalWeight1 = addedWeight1
totalWeight2 = addedWeight2
weight1LabelOutlet.text = String("\(totalWeight1)")
weight2LabelOutlet.text = String("\(totalWeight2)")
}
// Item Count
func addAllItems() {
var addedValue: Int = 0
for item in itemArray {
addedValue += item.quantity
}
totalItems = addedValue
totalCountLabelOutlet.text = String("\(totalItems)")
print("Total items: \(totalItems)")
}
//MARK: - Alert
func presentAlert() {
let alertController = UIAlertController(title: "Add Item", message: "Enter item info here", preferredStyle: .alert)
// AlertController Textfields
alertController.addTextField { (textField) in
textField.placeholder = "Name"
}
alertController.addTextField { (textField) in
textField.placeholder = "Weight 1"
textField.keyboardType = .decimalPad
}
alertController.addTextField { (textField) in
textField.placeholder = "Weight 2"
textField.keyboardType = .decimalPad
}
alertController.addTextField { (textField) in
textField.placeholder = "Quanity"
textField.keyboardType = .decimalPad
}
alertController.addTextField { (textField) in
textField.placeholder = "Notes"
}
// AlertController Actions
let continueAction = UIAlertAction(title: "Add", style: .default) { [self, weak alertController] _ in
guard let textFields = alertController?.textFields else { return }
if let userItemName = textFields[0].text,
let userItemWeight1 = textFields[1].text,
let userItemWeight2 = textFields[2].text,
let userItemQuanity = textFields[3].text,
let userItemNotes = textFields[4].text {
print("Name: \(userItemName)")
print("Item Weight 1: \(userItemWeight1)")
print("Item Weight 2: \(userItemWeight2)")
print("Item Quantity: \(userItemQuanity)")
print("Item Notes: \(userItemNotes)")
let userSubmittedItem = GearItem(itemName: userItemName, itemImage: UIImage(systemName: "photo.on.rectangle.angled")!, itemWeight1: Int(userItemWeight1) ?? 0, itemWeight2: Int(userItemWeight2) ?? 0, itemQuantity: Int(userItemQuanity) ?? 1, itemNotes: userItemNotes ?? "", creationPosition: itemArray.count + 1)
self.itemArray.append(userSubmittedItem)
gearTableView.reloadData()
updateUI()
}
}
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel)
cancelAction.setValue(UIColor.red, forKey: "titleTextColor")
alertController.addAction(continueAction)
alertController.addAction(cancelAction)
self.present(alertController,
animated: true)
}
//MARK: - TableView Protocol Functions
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return itemArray.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = gearTableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! GearComponentTableViewCell
cell.itemName.text = itemArray[indexPath.row].name
cell.itemImage.image = itemArray[indexPath.row].image
cell.itemWeight1.text = String("\(itemArray[indexPath.row].weight1)")
cell.itemWeight2.text = String("\(itemArray[indexPath.row].weight2)")
cell.itemQuanity.text = String("\(itemArray[indexPath.row].quantity)")
cell.itemNotes.text = itemArray[indexPath.row].notes
cell.tableViewCellPosition = indexPath.row
return cell
}
//MARK: - Swipeable TableViewCell
private func deleteItem(_ indexPath: IndexPath) {
itemArray.remove(at: indexPath.row)
gearTableView.reloadData()
updateUI()
print("Item Deleted")
}
func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let action = UIContextualAction(style: .normal, title: "Delete") { [weak self] (action, view, completionHandler) in
self?.deleteItem(indexPath)
completionHandler(true)
}
action.backgroundColor = .systemRed
return UISwipeActionsConfiguration(actions: [action])
}
}
extension GearComponentViewController: Stepper {
func refreshTableViewCell() {
print("arrayPosition: \(arrayPosition)")
// itemArray[arrayPosition].quantity += 1
// gearTableView.reloadData()
}
func stepperWasPressed(didIncrease: Bool, namePassed: String, userindexPath: Int) {
if didIncrease {
arrayPosition = userindexPath
print("arrayPosition: \(arrayPosition)")
// itemArray[userindexPath].quanity += 1
print("userindexPath: \(userindexPath) -- namePassed: \(namePassed) -- didIncrease: \(didIncrease)")
print("increase selected")
refreshTableViewCell()
}else {
arrayPosition = userindexPath
print("arrayPosition: \(arrayPosition)")
// itemArray[userindexPath].quanity -= 1
print("userindexPath: \(userindexPath) -- namePassed: \(namePassed) -- didIncrease: \(didIncrease)")
print("decrease selected")
refreshTableViewCell()
}
}
}
And here's an image of what my app looks like right now for reference.这是我的应用程序现在的样子以供参考。
The problem is in your delegate function.问题出在您的代表 function 中。 You try to delegate on a new instance of your GearComponentViewController().
您尝试委托 GearComponentViewController() 的新实例。 Try replacing the
var mainVC = GearComponentViewController()
in your custom cell Class with尝试将自定义单元格 Class 中的
var mainVC = GearComponentViewController()
替换为
var delegate:Stepper?
and call the delegate with并用
delegate?.stepperWasPressed(didIncrease:...
also don't forget to register your delegate on your GearComponentViewController() in the cellForRow function like也不要忘记在 cellForRow function 中的 GearComponentViewController() 上注册您的委托,例如
cell.delegate = self
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.