Clicked Header Section is scroll to top

2020-05-03 12:45发布

问题:

I have the following custom headerview implementation. When user clicks on headerView and it expands to show corresponding cells.

Let's imagine I have two sections. And the first section is expanded, and second one is collapsed. When I click the second section, I want this section to scroll to the top.

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    ExpandableHeaderFooterView *sectionHeaderView = [self.comboTableView dequeueReusableHeaderFooterViewWithIdentifier:SectionHeaderViewIdentifier];
    if (sectionHeaderView == nil)
    {
        sectionHeaderView = [[ExpandableHeaderFooterView alloc] initWithReuseIdentifier:SectionHeaderViewIdentifier];
    }
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(selectHeaderAction:)];
    [sectionHeaderView addGestureRecognizer:tapGesture];

    return sectionHeaderView;
}

-(void) selectHeaderAction :(UITapGestureRecognizer*) gestureRecognizer
{
    ExpandableHeaderFooterView* cell = (ExpandableHeaderFooterView*)gestureRecognizer.view;
    [self toggleSection:cell withSection: cell.section];
}

-(void)toggleSection:(ExpandableHeaderFooterView *)headerView withSection:(int)section
{
    ((ComboItem*)comboItemsArray[section]).expanded = !((ComboItem*)comboItemsArray[section]).expanded;

    [comboTableView beginUpdates];

    for (int i = 0; i< ((ComboItem*)comboItemsArray[section]).allComboItems.count; i++)
    {
        NSArray* rowsToReload = [NSArray arrayWithObjects:[NSIndexPath indexPathForRow:i inSection:section], nil];
        [comboTableView reloadRowsAtIndexPaths:rowsToReload
                                   withRowAnimation:UITableViewRowAnimationFade];
    }

    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:section];

    [comboTableView scrollToRowAtIndexPath:indexPath
                          atScrollPosition:UITableViewScrollPositionTop
                                  animated:YES];

    [comboTableView endUpdates];
}

回答1:

Since Fade takes about half a second to execute, you will see that flick. What you need to do is either giving a small delay to TableViewScroll, or just using:

[CATransaction begin];
[comboTableView beginUpdates];
[CATransaction setCompletionBlock: ^{
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:section];

   [comboTableView scrollToRowAtIndexPath:indexPath
                          atScrollPosition:UITableViewScrollPositionTop
                                  animated:YES];
}];
for (int i = 0; i< ((ComboItem*)comboItemsArray[section]).allComboItems.count; i++)
    {
        NSArray* rowsToReload = [NSArray arrayWithObjects:[NSIndexPath indexPathForRow:i inSection:section], nil];
        [comboTableView reloadRowsAtIndexPaths:rowsToReload
                                   withRowAnimation:UITableViewRowAnimationFade];
    }
[comboTableView endUpdates];
[CATransaction commit];