HongKongTom
HongKongTom

Reputation: 207

Custom tableview(cell) with checkmark

I want to do an app like a to-do app with a tableview. When I hit the add button (system provided by self.navigationItem.rightBarButtonItem = addButton) a new tableview appears and a list with given items (provided by an entity of coreData). Now I want to set by a touch in a cell a checkmark and at the end I want to press the "save" button. For taking all selected (checked items) in the first tableview.

I thought to do it in didSelectRowAtIndexPath. But when I scroll up and down I get checkmarks even in cells that I didn t checked. then I tried the following code:

incellForRowAtIndexPath

cell.detailObejct = (dataOfEntity[indexPath.row])
if checked[indexPath.row] == false {

    cell.accessoryType = .None
}
else if checked[indexPath.row] == true {

    cell.accessoryType = .Checkmark
}

and in

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    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
        }
}

but when I run that code I get an error that says array index out of range. The array is declared as

var checked = [Bool]()

Upvotes: 2

Views: 642

Answers (3)

HongKongTom
HongKongTom

Reputation: 207

Thanks @dsieczko I changed some details in my code:

cell.detailObejct = (dataOfEntity[indexPath.row])
cell.accessoryType = .None // THIS IS MANDATORY
if checked[indexPath.row] == false {

    cell.accessoryType = .None
}
else if checked[indexPath.row] == true {

    cell.accessoryType = .Checkmark
}

and the did select looks like:

 override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    if let cell = tableView.cellForRowAtIndexPath(indexPath) {
        if cell.accessoryType == .Checkmark
        {
            cell.accessoryType = .None
            //checked[indexPath.row] = false // this line removes now the entry instead of setting it only to false
checked[indexPath.row] = nil
        }
        else
        {
            cell.accessoryType = .Checkmark
            checked[indexPath.row] = true
        }
}

and of cause the dict:

var checked = Dictionary<Int, Bool>()

Upvotes: 0

Satheesh
Satheesh

Reputation: 11276

Gotcha you are not adding any elements to your checked array I mean it has 0 elements but you are trying to take out an item in the data source method so initialise the checked array with all false values since initially no rows are selected,

for _ in 0...tableItems.count{ //tableItems should be your data source count
  checked.append(false)
}

I tried the same and everything works fine for me, add the above statement in viewDidLoad()

Upvotes: 1

dsieczko
dsieczko

Reputation: 423

It looks like you're not taking into account the size of your original dataSource.

You either need to instantiate a dictionary for your checked variable,

var checked = Dictionary<Int, Bool>()

to track the index inside your original dataSource.

Or instantiate an array with a default size and value

var checked : Array<Bool>!

override func viewDidLoad() {
    // You need the size of your data at this point
    checked = [Bool](count: dataSource.count, repeatedValue: false)
}

Please let me know if there is anything else I can do to help.

Upvotes: 2

Related Questions