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

Можете ли вы настраивать анимацию для встраиваемых ячеек UITableView?

У меня есть UITableView, который заполняется NSFetchedResultsController.

В начальной загрузке таблицы я хотел бы, чтобы ячейки были анимированы, но я хотел бы сделать немного больше пользовательской анимации, чем

[tableView insertRowsAtIndexPaths:withRowAnimation:];

Позволяет. В частности, я хотел бы замедлить анимацию и заставить их летать со стороны определенным образом. Я не смог достичь этого с помощью констант UITableViewRowAnimation. Есть ли способ использовать Core Animation для выполнения именно того, что я хочу, или мне нужно придерживаться анимаций UIKit в этом конкретном экземпляре?

Спасибо за любую помощь!

Joel

4b9b3361

Ответ 1

НОВОЕ РЕШЕНИЕ (2017-12-12)

Добавление версии Swift 4.0 метода анимации. Затем он должен быть реализован так же, как решение ниже:

func animate() {
    for cell in self.tableView.visibleCells {
        cell.frame = CGRect(x: self.tableView.frame.size.width, y: cell.frame.origin.y, width: cell.frame.size.width, height: cell.frame.size.height)
        UIView.animate(withDuration: 1.0) {
            cell.frame = CGRect(x: 0, y: cell.frame.origin.y, width: cell.frame.size.width, height: cell.frame.size.height)
        }
    }
}

NEWER SOLUTION (2015-09-05)

Добавление версии метода анимации Swift 2.0. Затем он должен быть реализован так же, как решение ниже:

func animate() {
    for cell in self.tableView.visibleCells {
        cell.frame = CGRectMake(320, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)
        UIView.animateWithDuration(1.0) {
            cell.frame = CGRectMake(0, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)
        }
    }
}

NEW SOLUTION (2014-09-28)

Я немного переработал решение, чтобы сделать реализацию более простой и заставить ее работать с iOS8. Все, что вам нужно сделать, это добавить этот метод animate в свой TableViewController и вызвать его всякий раз, когда вы хотите его оживить (например, в вашем методе перезагрузки, но вы можете его вызвать в любое время):

- (void)animate
{
    [[self.tableView visibleCells] enumerateObjectsUsingBlock:^(UITableViewCell *cell, NSUInteger idx, BOOL *stop) {
        [cell setFrame:CGRectMake(320, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)];
        [UIView animateWithDuration:1 animations:^{
            [cell setFrame:CGRectMake(0, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)];
        }];
    }];
}

Снова измените анимацию, как вам нравится. Этот конкретный код будет анимировать ячейки справа с низкой скоростью.

OLD SOLUTION (2013-06-06)

Вы можете сделать это, выполнив свой собственный UITableView и переопределив метод insertRowsAtIndexPaths. Вот пример того, как это могло бы выглядеть, когда клетки будут сдвигаться с правой стороны, очень медленно (1 секунда анимации):

- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation
{
    for (NSIndexPath *indexPath in indexPaths)
    {
        UITableViewCell *cell = [self cellForRowAtIndexPath:indexPath];
        [cell setFrame:CGRectMake(320, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)];

        [UIView beginAnimations:NULL context:nil];
        [UIView setAnimationDuration:1];
        [cell setFrame:CGRectMake(0, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)];
        [UIView commitAnimations];
    }
}

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

К.П

Метод reloadData должен выглядеть примерно так:

- (void)reloadData
{
    [super reloadData];
    NSMutableArray *indexPaths = [[NSMutableArray alloc] init];
    for (int i = 0; i < [_data count]; i++)
        [indexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]];
    [self insertRowsAtIndexPaths:indexPaths withRowAnimation:0];
}

Ответ 2

materik answer не работал у меня с iOS 7.1 SDK, у меня есть nil после вызова [self cellForRowAtIndexPath:indexPath];

Здесь мой код в подклассе UITableView:

- (void)insertRowsAtIndexPaths:(NSArray *)indexPaths
              withRowAnimation:(UITableViewRowAnimation)animation
{
    [super insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationNone];
    [self endUpdates]; // Populates UITableView with data
    [self beginUpdates];
    for (NSIndexPath *indexPath in indexPaths) {
        __block UITableViewCell *cell = [super cellForRowAtIndexPath:indexPath];
        if (cell) { // If indexPath isn't visible we'll get nil here
            // Custom animation
            CGRect frame = cell.frame;
            frame.origin.x = cell.frame.size.width;
            cell.frame = frame;
            frame.origin.x = 0;
            void (^animationsBlock)() = ^{
                cell.frame = frame;
            };
            if ([[UIView class] respondsToSelector:
                 @selector(animateWithDuration:delay:usingSpringWithDamping:
                           initialSpringVelocity:options:animations:completion:)]) {
                [UIView animateWithDuration:0.3
                                      delay:0
                     usingSpringWithDamping:0.5
                      initialSpringVelocity:0
                                    options:0
                                 animations:animationsBlock
                                 completion:NULL];
            } else {
                [UIView animateWithDuration:0.3
                                      delay:0
                                    options:UIViewAnimationOptionCurveEaseIn
                                 animations:animationsBlock
                                 completion:NULL];
            }
        }
    }
}

Ответ 3

Используйте это:

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{
         [cell setFrame:CGRectMake(320, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)];
            [UIView animateWithDuration:2 animations:^{
                [cell setFrame:CGRectMake(100, cell.frame.origin.y, cell.frame.size.width, cell.frame.size.height)];

            }];

}

Ответ 4

Swift 3.0 версия Маттиаса Эрикссона Отвечать

func animate() {
    for cell in tblView.visibleCells {
        cell.frame = CGRect(x:320, y:cell.frame.origin.y, width:cell.frame.size.width, height:cell.frame.size.height)
            UIView.animate(withDuration: 1.0) {
                cell.frame = CGRect(x:0, y:cell.frame.origin.y, width:cell.frame.size.width, height:cell.frame.size.height)
            }
    }
}