ios - grouped - uitableview insertrows animation



Странная UITableView вставка/удаление строки анимации (3)

Я вижу странный эффект при вставке / удалении UITableViewCell в UITableView с анимацией (UITableViewRowAnimationTop).

Анимация возникает, когда ячейка для вставки намного больше, чем ячейка выше.

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

Here проект Xcode из видео.

Ниже приведен код вставки ячейки / анимации.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 2 + self.thirdCellVisible;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:NO];

    if (indexPath.row == 1)
    {
        if (self.thirdCellVisible)
        {
            self.thirdCellVisible = !self.thirdCellVisible;
            [tableView deleteRowsAtIndexPaths:@[self.thirdCellIndexPath]
                             withRowAnimation:UITableViewRowAnimationTop];
        }
        else
        {
            self.thirdCellVisible = !self.thirdCellVisible;
            [tableView insertRowsAtIndexPaths:@[self.thirdCellIndexPath]
                             withRowAnimation:UITableViewRowAnimationTop];
        }
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == self.thirdCellIndexPath.row)
    {
        return 100.0f;
    }

    return 44.0f;
}

Answer #1

Вам придется позвонить

[tableView beginUpdates] 

а также

[tableView endUpdates] 

до и после вызова методов вставки / удаления, как показано ниже:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 2 + self.thirdCellVisible;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:NO];

    if (indexPath.row == 1)
    {
        if (self.thirdCellVisible)
        {
            self.thirdCellVisible = !self.thirdCellVisible;
            [self.tableView beginUpdates];

            [tableView deleteRowsAtIndexPaths:@[self.thirdCellIndexPath]
                             withRowAnimation:UITableViewRowAnimationTop];

            [self.tableView endUpdates];

        }
        else
        {
            self.thirdCellVisible = !self.thirdCellVisible;
            [self.tableView beginUpdates];

            [tableView insertRowsAtIndexPaths:@[self.thirdCellIndexPath]
                             withRowAnimation:UITableViewRowAnimationTop];

            [self.tableView endUpdates];

        }
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == self.thirdCellIndexPath.row)
    {
        return 100.0f;
    }

    return 44.0f;
}

Answer #2

Вот ссылка на видео моего рабочего кода: https://dl.dropboxusercontent.com/u/30316681/480.mov

Ниже мой рабочий код:

@interface ViewController ()

@property (nonatomic, readwrite) BOOL thirdCellVisible;
@property (nonatomic, strong) NSIndexPath *thirdCellIndexPath;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.thirdCellIndexPath = [NSIndexPath indexPathForRow:2 inSection:0];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 2 + self.thirdCellVisible;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row == self.thirdCellIndexPath.row)
    {
        return 100.0f;
    }

    return 44.0f;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:NO];

    if (indexPath.row == 1)
    {
        if (self.thirdCellVisible)
        {
            self.thirdCellVisible = !self.thirdCellVisible;
            [tableView deleteRowsAtIndexPaths:@[self.thirdCellIndexPath]
                         withRowAnimation:UITableViewRowAnimationTop];
        }
        else
        {
            self.thirdCellVisible = !self.thirdCellVisible;
            [tableView insertRowsAtIndexPaths:@[self.thirdCellIndexPath]
                         withRowAnimation:UITableViewRowAnimationTop];
        }
    }
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellId = @"id";

    UITableViewCell *cell = [tableView dequeueReusableHeaderFooterViewWithIdentifier:cellId];

    if(cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
    }

    NSString *cellTitle = [NSString stringWithFormat:@"Cell %ld", (long)indexPath.row];

    cell.textLabel.text = cellTitle;

    if(indexPath.row == 2)
        cell.backgroundColor = [UIColor yellowColor];

    else
        cell.backgroundColor = [UIColor clearColor];

    return cell;
}

@end

Answer #3

По словам Apple, здесь :

Чтобы анимировать пакетную вставку, удаление и перезагрузку строк и разделов, вызовите соответствующие методы в блоке анимации, определяемом последовательными вызовами beginUpdates и endUpdates. Если вы не вызываете методы вставки, удаления и перезагрузки в этом блоке, индексы строк и разделов могут быть недействительными. Вызовы beginUpdates и endUpdates могут быть вложенными; все индексы обрабатываются так, как если бы существовал только внешний блок обновления.

По завершении блока, то есть после возврата endUpdates, табличное представление запрашивает свой источник данных и делегирует, как обычно, для данных строк и разделов. Таким образом, объекты коллекции, поддерживающие табличное представление, должны быть обновлены с учетом новых или удаленных строк или разделов.

Вам придется вызывать [tableView beginUpdates] и [tableView endUpdates] до и после вызова методов вставки / удаления соответственно.

Пример предоставлен Apple по вышеуказанной ссылке.

Примечание . Если элементы массива и табличного представления не синхронизированы, без вызовов начала / конца будет выдано исключение.

Предложение : попробуйте сначала с withRowAnimation:UITableViewRowAnimationAutomatic





animation