uitableviewcore-animationios7.1catransaction

CATransaction insertRowsAtIndexPaths, animation doesn't end


Our app has a tableview that allows users to minimize/maximize its sections. There are also animations tied to hiding/showing rows depending on the user's input, as well as being connected to different devices (via Bluetooth 4.0). Because of the different sources of animations, we set up a scheduler to handle one animation at a time so that we didn't get any crashes tied to the number of rows/sections being out of sync after a [tableview endUpdates]. It's been working really well for our purposes.

However, a new section in our table has been giving me a bit of grief. Depending on the device that is connected to the iPad, the section either has 1 row or it has 8-9 rows. The rest of the rows have a height of 0. The section minimizes/maximizes just fine when it has 8-9 rows. When the section only has one row though, the insertRowsAtIndexPaths animation for the table does not complete until the section's row is off the screen. So unless the user changes tabs or scrolls down far enough for the table to push it off the screen, no other section can be minimized/maximized due to our scheduler checking first if it's already busy. Here is the code that gets called for the animations:

-(void)animateTableUsingAnimationType:(NSNumber*)aniType
{
    static int animationID = -1;
    if(tableAnimationBusy)
    {
        [self performSelector:@selector(animateTableUsingAnimationType:) withObject:aniType afterDelay:.05f];
    }
    else
    {
        tableAnimationBusy = true;
        tat = [aniType intValue];
        [CATransaction begin];
        [CATransaction setCompletionBlock:^{
            NSLog(@"Animation %d is complete!", tat);
            tableAnimationBusy = false;
        }];

        //if-else if blocks checking for the animationID
        //if open section 2
            [self animateOpenTableSection:2]
        else //undefined ID
            tableAnimationBusy = false;

        [CATransaction commit];
        [self setUpLabelText];
    }
}

and the animateOpenTableSection is:

-(void)animateOpenTableSection:(NSInteger)section
{
    NSLog(@"Calling open on section: %d", section);
    if (section == 2)
    {
        [self.tableView beginUpdates];
        openFlagSettingsRowCount = fsr_COUNT; //max row count for section

        [[MCUISectionHandler sharedInstance] sectionTouched:YES forSection:MCUISH_SECTION_NAME__FLAG];
        NSMutableArray *indexPathsToInsert = [[NSMutableArray alloc] init];
        for (NSInteger i = 0; i < fsr_COUNT; i++) {
            [indexPathsToInsert addObject:[NSIndexPath indexPathForRow:i inSection:section]];
        }
        [self.tableView insertRowsAtIndexPaths:indexPathsToInsert withRowAnimation:UITableViewRowAnimationFade];
        [self.tableView endUpdates];
    }
}

As you can see, I have debug statements in the animateOpenTableSection function, as well as the completion block in animateTableUsingAnimationType. The latter never gets called until the single row is off the screen. Any ideas as to why the tableview wouldn't let go of the CATransaction?


Solution

  • We were able to solve this problem and I forgot to post what I found out about our app. The reason the tableview wouldn't let go of the CATransaction was because of UIActivityIndicator subviews in the rows. They were being animated and so the CATransaction never ended because it was waiting for one or more UIActivityIndicators to stop animating.

    So for those who may run into this problem, check to see if any subviews are being animated.