Подтвердить что ты не робот

Позиция нижнего колонтитула секции UITableView после endUpdates

На ios8 я использую контроллер представлений таблицы данных ядра, и после удаления строк мой нижний колонтитул раздела внезапно доходит до нижней части UITableView. Когда я просматриваю представление таблицы, нижний колонтитул возвращается к своему месту. Как это можно исправить и почему это происходит?

Вот код на всякий случай.

- (void)controller:(NSFetchedResultsController *)controller
   didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath
     forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{       
    if (!self.suspendAutomaticTrackingOfChangesInManagedObjectContext)
    {
        switch(type)
        {
            case NSFetchedResultsChangeInsert:
                [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;

            case NSFetchedResultsChangeDelete:
                [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
                break;

            case NSFetchedResultsChangeUpdate:
                [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;

            case NSFetchedResultsChangeMove:
                [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
        }
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    if (self.beganUpdates)
    {
       [self.tableView endUpdates];
    }
}
4b9b3361

Ответ 1

Это изменение анимации iOS 8. Вы должны изменить стиль tableview на "сгруппированный", чтобы нижний колонтитул раздела не переместился в bootom uitableview

Ответ 2

Я столкнулся с одной и той же проблемой. Когда я использую insertRowsAtIndexPaths, нижний колонтитул уходит в нижнюю часть. Также заметили, что если вы вызовеете reloadData в представлении таблицы, это устранит проблему, поэтому я сделал следующее:

[CATransaction begin];
[CATransaction setCompletionBlock: ^{
    // Code to be executed upon completion
    [tableView reloadData];
}];

[tableView insertRowsAtIndexPaths:insertIndexPaths withRowAnimation:UITableViewRowAnimationLeft];
[CATransaction commit]; 

Все, что он делает, это перезагрузка таблицы при завершении анимации вставки... Это не настоящее решение, скорее как избежать проблемы, но оно скрывает проблему, пока кто-то не объяснит, почему это происходит и как это исправить....

Ответ 3

Я столкнулся с той же проблемой и приложил много усилий, чтобы попытаться ее решить. И теперь, наконец!

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {

        NATask *task = sections[indexPath.section][indexPath.row];
        [sections[indexPath.section] removeObjectAtIndex:indexPath.row];
        [appDelegate.managedObjectContext deleteObject:task];

        [CATransaction begin];
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];

        UIView *footerView = [tableView footerViewForSection:indexPath.section];
        CABasicAnimation *animation = [[footerView.layer animationForKey:@"position"] mutableCopy];
        CGPoint fromValue = [(NSValue *)animation.fromValue CGPointValue];
        animation.toValue = [NSValue valueWithCGPoint:CGPointMake(0, fromValue.y - 44)];
        [footerView.layer removeAnimationForKey:@"position"];
        [footerView.layer addAnimation:animation forKey:@"position"];
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, .4 * NSEC_PER_SEC);
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            [tableView reloadData];
        });

        [CATransaction commit];
    }
}

Конечно, это не самое идеальное решение, но оно работает! Я почти две недели боролся с этой проблемой, надеюсь, по крайней мере, полезен кому-то.

Ответ 4

Я столкнулся с той же проблемой. Ни один из ответов до сих пор не дал мне именно то, что я искал. Установка вида таблицы на "сгруппированные" не была поведением, которое я хотел, а другие решения по-прежнему приводили к тому, что нижний колонтитул был кратковременно расположен в нижней части таблицы, пока не была вызвана reloadData, и они внезапно вернули ее в правильное положение.

Ниже мое решение, которое гладко оживляет его там, где оно должно быть.

NSIndexPath* iPath = [NSIndexPath indexPathForRow:_lineItemArray.count-1 inSection:0];

// Calculate the Y position of the bottom of the footer within the table view frame.
CGFloat footerBaseY = (_footer.y + _footer.height) - _sTableView.contentOffset.y;
// Calculate the Y position of the bottom taking into account the bottom content inset.
CGFloat tableViewContentBottomY = _sTableView.height - _sTableView.contentInset.bottom;

if (footerBaseY < tableViewContentBottomY) {
    [_sTableView insertRowsAtIndexPaths:@[iPath] withRowAnimation:UITableViewRowAnimationBottom];
    [UIView animateWithDuration:0.3
                     animations:^{
                         CGFloat y = _lineItemArray.count * [_sTableView rectForRowAtIndexPath:iPath].size.height;
                         CGFloat newBaseY = (y + _footer.height) - _sTableView.contentOffset.y;

                         if (newBaseY < tableViewContentBottomY) {
                             _footer.y = y;
                         } else {
                             // The footer is within a cell height away from the bottom.  Subtract the diff from the new y.
                             _footer.y = y - (newBaseY - tableViewContentBottomY);
                         }
                     } completion:^(BOOL finished) {
                         // This ensures that the bottom row animates up if the footer was within a cell height away from the bottom.
                         [_sTableView scrollToRowAtIndexPath:iPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
                     }];
} else {
    // The footer was already at the bottom of the vew so I'm animating the added row up.
    [_sTableView insertRowsAtIndexPaths:@[iPath] withRowAnimation:UITableViewRowAnimationBottom];
    [_sTableView scrollToRowAtIndexPath:iPath atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}

Ответ 5

Мне все еще нужно, чтобы заголовок и нижний колонтитул секции были липкими. Чтобы вместо изменения стиля tableview в Grouped я просто сделал reloadSection после удаления строк...