0
votes

I get this assertion when trying to update my tableview when clicking on a section header.

* Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-2839.5/UITableView.m:1264

I am just trying to hide and show custom cells whenever I click on a section header view.

code works fine if I replace the update code with reload data. but that's not smooth :(

- (void)noteSectionHeader:(UTNoteSectionHeader *)noteSectionHeader sectionTapped:(NSInteger)section
{
    UTNoteItem* noteItem = self.notes[section];
    BOOL alreadySelected = noteItem.selected;
    if (alreadySelected) {
        self.selectedSection = NSNotFound;
        [self setSelected:NO forSection:section];
    }
    else {
        self.selectedSection = section;
        [self setSelected:YES forSection:section];
    }

    [self updateSections];
}

- (void)setSelected:(BOOL)selected forSection:(NSInteger)section
{
    UTNoteItem* noteItem = self.notes[section];
    noteItem.selected = selected;
    for (UTNoteItem* tmpItem in self.notes) {
        if (tmpItem != noteItem) {
            tmpItem.selected = NO;
        }
    }
}

- (void)updateSections
{
    NSMutableArray* deletePaths = [[NSMutableArray alloc] init];
    NSMutableArray* addPaths = [[NSMutableArray alloc] init];


    for (UTNoteItem* item in self.notes) {
        if (item.selected) {
            [addPaths addObject:[NSIndexPath indexPathForRow:0 inSection:[self.notes indexOfObject:item]]];
        }
        else {
            [deletePaths addObject:[NSIndexPath indexPathForRow:0 inSection:[self.notes indexOfObject:item]]];
        }
    }

    [self.tableView beginUpdates];
    [self.tableView deleteRowsAtIndexPaths:deletePaths withRowAnimation:YES];
    [self.tableView insertRowsAtIndexPaths:addPaths withRowAnimation:YES];
    [self.tableView endUpdates];

}


#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return self.notes.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    UTNoteItem* itemNote = self.notes[section];
    if (itemNote.selected) return 1;
    return 0;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 40;
}

EDIT:

Here is my new implementation:

-

 (void)noteSectionHeader:(UTNoteSectionHeader *)noteSectionHeader sectionTapped:(NSInteger)section
{
    /* Check if a section is opened */
    if (self.selectedSection != NSNotFound) {
        /* A section is open, get the item */
        UTNoteItem* theItem = self.notes[self.selectedSection];
        /* if the item is the section opened, close it */
        if (self.selectedSection == section) {
            theItem.selected = NO;
            self.selectedSection = NSNotFound;

        }
        /* The item is not the section, so open it, and close the previous item */
        else {
            theItem.selected = YES;
            UTNoteItem* prevItem = self.notes[self.selectedSection];
            prevItem.selected = NO;
            self.selectedSection = section;
        }
    }
    /* Nothin is open, just open the section */
    else {
        self.selectedSection = section;
        UTNoteItem* openItem = self.notes[self.selectedSection];
        openItem.selected = YES;
    }
    /* Reload the selected section.. this will not reload the other sections? */
    [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:section] withRowAnimation:UITableViewRowAnimationAutomatic];
}
1

1 Answers

1
votes

I have had a similar problem, however I perform a reload like so:

- (void)noteSectionHeader:(UTNoteSectionHeader *)noteSectionHeader sectionTapped:(NSInteger)section
 {
        //check our action
        if(<will hide section>) {
            //hide section
            <some action>
        } else {
             //show section
             <some action>
        }
        [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationAutomatic];
    }

and it reloads again differently with a forced update:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSInteger nRows = 0; //no rows when closed

    if(<check section is open>) {
        nRows +=<number of data items shown>;
    }

    return nRows;
}

Where the indexpath.section is the section I wish to hide or show. it is smooth and stable. Deleting and adding rows is a little dangerous in my opinion, tableviews are very good at doing animated reloads on individual sections or cells.