How to uncheck all rows using UITableViewCellAccessoryCheckmark

I’ve got a UITableView with each row containing a checkbox using UITableViewCellAccessoryCheckmark. I can’t figure out how to uncheck all the checkboxes using the didSelectRowAtIndexPath method.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {  

    UITableViewCell *oldCell;

    int count = [self.myTableRowNamesArray count];

    for (NSUInteger i = 0; i < count; ++i) {                                
        // Uncheck all checkboxes
        // OF COURSE THIS DOESN'T WORK
        // BECAUSE i IS AN INTEGER AND INDEXPATH IS A POINTER
        FOO: oldCell = [myTableView cellForRowAtIndexPath:(int)i];
        // GOOD CODE:
        oldCell = [penanceOptionsTableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:i inSection:0]];
        oldCell.accessoryType = UITableViewCellAccessoryNone;
    }
    UITableViewCell *newCell = [myTableView cellForRowAtIndexPath:indexPath];
    newCell.accessoryType = UITableViewCellAccessoryCheckmark;
}

  • Need any example of UILocalNotifications
  • Is using subviews in Alert undocumented
  • Displaying an EAGLView with transparent background on a UIImageView
  • Faster alternative to glReadPixels in iPhone OpenGL ES 2.0
  • XCode5 simulator: unknown option character `X' in: -Xlinker
  • adding a UITableView programmatically to a UIViewController
  • 4 Solutions Collect From Internet About “How to uncheck all rows using UITableViewCellAccessoryCheckmark”

    Yes, cellForRowAtIndexPath: uses NSIndexPath instead of integer so make indexpath by using

    indexPathForRow:inSection:
    

    if you are using one section then your loop is fine just pass i in row and 0 for section.

    Instead of modifying the .accessoryType of all cells in didSelectRowAtIndexPath:, I suggest storing the selected index in some ivar, and change the .accessoryType in the data source’s -tableView:cellForRowAtIndexPath: method, i.e.

    -(void)tableView:(UITableView*)tableView didSelectRowAtIndexPath:(NSIndexPath*)indexPath { 
       self.selectedIndexPath = indexPath;
       [tableView reloadData];
    }
    
    -(UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath {
       ...
       cell.accessoryType = [indexPath compare:self.selectedIndexPath] == NSOrderedSame
                              ? UITableViewCellAccessoryCheckmark
                              : UITableViewCellAccessoryNone;
       ...
    }
    

    With this, only visible cells will be affected, and the million other cells outside of the screen won’t need to be modified.


    Quite right, here’s a full implementation in Swift in the general case of selecting a cell .. you’d use selectedIndexPath elsewhere in the class as you see fit. For example, in cellForRowAtIndexPath to choose the appropriate cell prototype.

    //  SelectingTableViewController
    
    import UIKit
    
    class SelectingTableViewController: UITableViewController   
        {
        internal var selectedIndexPath:NSIndexPath? = nil
    
        override func viewDidLoad()
            {
            super.viewDidLoad()
            tableView.estimatedRowHeight = 68.0
            tableView.rowHeight = UITableViewAutomaticDimension
    
            self.clearsSelectionOnViewWillAppear = false;
            }
    
        override func tableView
            (tableView:UITableView, didSelectRowAtIndexPath indexPath:NSIndexPath)
                {
                print("did select....")
    
                // in fact, was this very row selected,
                // and the user is clicking to deselect it...
                // if you don't want "click a selected row to deselect"
                // then on't include this clause.
                if selectedIndexPath == indexPath
                    {
                    print("(user clicked on selected to deselect)")
                    selectedIndexPath = nil
                    tableView.reloadRowsAtIndexPaths(
                        [indexPath],
                        withRowAnimation:UITableViewRowAnimation.None)
    
                    tableView.deselectRowAtIndexPath(indexPath, animated:false)
                    return
                    }
    
                // in fact, was some other row selected??
                // user is changing to this row? if so, also deselect that row
                if selectedIndexPath != nil
                    {
                    let pleaseRedrawMe = selectedIndexPath!
                    // (note that it will be drawn un-selected
                    // since we're chaging the 'selectedIndexPath' global)
                    selectedIndexPath = indexPath
                    tableView.reloadRowsAtIndexPaths(
                        [pleaseRedrawMe, indexPath],
                        withRowAnimation:UITableViewRowAnimation.None)
                    return;
                    }
    
                // no previous selection.
                // simply select that new one the user just touched.
                // note that you can not use Apple's willDeselectRowAtIndexPath
                // functions ... because they are freaky
                selectedIndexPath = indexPath
                tableView.reloadRowsAtIndexPaths(
                    [indexPath],
                    withRowAnimation:UITableViewRowAnimation.None)
    
                }
    
        }
    
    for (UITableViewCell *cell in [myTableView visibleCells]) {
        cell.accessoryType = UITableViewCellAccessoryNone;
    }
    

    But really, you’d be better off just modifying the one cell that actually has the checkmark set. You have to have stored this information somewhere in your model anyway.

    You’re probably setting some kind of property with this method.
    So what i do is:

    - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
    {
        // 1. first unsetting the property
        [object someProperty:nil];
    
        // 2. call the reloadData method to uncheck all the checkmarks
        [tableView reloadData];
    
        // 3. check the selected cell
        UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
        [cell setAccessoryType:UITableViewCellAccessoryCheckmark];
    
        // 4. set the checked property
        [object setSomeProperty:[indexpath row]];
    }
    

    And in my cellForRowAtIndexPath methods i got something like the following code:

        if([object someProperty] == [indexpath row]){
            [cell setAccessoryType:UITableViewCellAccessoryCheckmark];        
        } else {
            [cell setAccessoryType:UITableViewCellAccessoryNone];
        }