I am making an app that requires the user to tap on multiple cells in order to select them. when they tap on a cell, a .Checkmark accessory item will appear. For some reason though whenever I try and get to that VC the app crashes and I get the following error messages on line 8(if !checked[indexPath.row]):
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
{
let cell: InstrumentTableCell! = tableView.dequeueReusableCellWithIdentifier(identifier) as? InstrumentTableCell
cell.configurateTheCell(recipies[indexPath.row])
if !checked[indexPath.row] {
cell.accessoryType = .None
} else if checked[indexPath.row] {
cell.accessoryType = .Checkmark
}
return cell
}
and this is my working checked method:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
tableView.deselectRowAtIndexPath(indexPath, animated: true)
if let cell = tableView.cellForRowAtIndexPath(indexPath) {
if cell.accessoryType == .Checkmark {
cell.accessoryType = .None
checked[indexPath.row] = false
} else {
cell.accessoryType = .Checkmark
checked[indexPath.row] = true
}
}
}
Your problem is that you only store items in your checked
array when tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
is called. However, that method is only called when you actually select a row.
tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath)
on the other hand is called each and every time you need to render a new table cell.
So when you in cellForRowAtIndexPath
asks:
if !checked[indexPath.row]
then you can not be sure that checked
actually contains anything. For instance the first time you start rendering your cells, your checked
array does not contain any values and therefore it crashes when you ask it for a value on a position that it does not have a value for.
One solution could be to initialize your checked
array to contain all false
values. I'm guessing you have some model array called recipies
so you could do something like:
for (index, _) in recipies.enumerate() {
checked.append(false)
}
Or as @AaronBrager suggests in the comments below (which is way prettier :))
checked = Array(count:recipies.count, repeatedValue:false)
that way you are sure that your checked array is properly initialized with the same number of elements as you have recipies.
Another option could be to let the individual elements in recipies
know whether or not they are checked.
Hope this makes sense and helps you.