Анимация UITableViewCell при прокрутке

Я реализовал Cocoa with Love в примере для выбора нескольких строк который включает создание пользовательского UITableViewCell, который инициирует анимацию в layoutSubviews для отображения флажков слева от каждой строки, например:

- (void)layoutSubviews
{
    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationBeginsFromCurrentState:YES];

    [super layoutSubviews];

    if (((UITableView *)self.superview).isEditing)
    {
        CGRect contentFrame = self.contentView.frame;
        contentFrame.origin.x = EDITING_HORIZONTAL_OFFSET;
        self.contentView.frame = contentFrame;
    }
    else
    {
        CGRect contentFrame = self.contentView.frame;
        contentFrame.origin.x = 0;
        self.contentView.frame = contentFrame;
    }

    [UIView commitAnimations];
}

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

Это понятно, учитывая, что для setAnimationBeginsFromCurrentState установлено значение YES, а для рядов ниже в UITableView положение кадра еще не обновлено. Чтобы решить эту проблему, я попытался использовать willDisplayCell, чтобы переопределить анимацию для ячеек, которые становятся видимыми, когда UITableView находится в режиме редактирования. По сути, обход анимации и немедленное обновление фрейма строк, чтобы он выглядел так, как будто ячейка уже анимирована на место, например так:

/*
 Since we animate the editing transitions, we need to ensure that all animations are cancelled
 when a cell is scheduled to appear, so that things happen instantly.
 */
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    [cell.contentView.layer removeAllAnimations];   

    if(tableView.isEditing) {
        CGRect contentFrame = cell.contentView.frame;
        contentFrame.origin.x = EDITING_HORIZONTAL_OFFSET;
        cell.contentView.frame = contentFrame;
    } else {
        CGRect contentFrame = cell.contentView.frame;
        contentFrame.origin.x = 0;
        cell.contentView.frame = contentFrame;
    }
}

К сожалению, это, кажется, не имеет никакого эффекта. Кто-нибудь знает, как я могу решить эту проблему?


person ndg    schedule 25.11.2010    source источник


Ответы (1)


Не уверен, что вам все еще нужен ответ на этот вопрос, но я столкнулся с точно такой же проблемой, поэтому решил поделиться своим решением. Я реализовал Multi-Selection так же, как это описано в блоге Cocoa with Love, о котором вы упомянули.

В методе cellAtIndexPath DataSource, когда я создаю новую ячейку (не в том случае, если ячейка уже находится в очереди повторно используемых ячеек), я проверяю, находится ли tableView в режиме редактирования, и если это так, я устанавливаю свойство в ячейке (я создал свой собственный пользовательскую ячейку со свойством EnableAnimation) в false, поэтому, когда он получает обратный вызов SetEditing, он не будет анимировать ячейку, вместо этого он просто установит фрейм. В конструкторе класса Cell я устанавливаю для EnableAnimation значение true, когда вызывается обратный вызов SetEditing, я устанавливаю EnableAnimation для передаваемого аргумента анимации. Надеюсь, это поможет.

person JonnyWalker81    schedule 03.11.2011