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

UICollectionVIew: оживить ячейки, когда они прокручиваются

Я хотел бы, чтобы элементы в моем UICollectionView отображались для просмотра, когда пользователь прокручивает список (я использую подкласс UICollectionViewFlowLayout).

Я указываю позицию в Менеджере макетов, то, что я хотел бы сделать, это также указать начальное преобразование и применить это в анимации в правильное время (когда ячейка сначала появится на экране). Чтобы увидеть эффект, который я имею в виду, проверьте приложение Google Plus на iOS. В идеале другое преобразование зависит от местоположения ячейки.

Кажется, я не могу найти способ узнать, когда отображается ячейка (эквивалент willDisplayCell, как есть на UITableView), или любые указатели на то, куда идти для этого.

Любые предложения?

Вы можете просто выделить анимацию в Google Plus на этом снимке экрана: Example in the Google Plus App

Кроме того, взгляните на iPhoto на iPad. Я не знаю, использует ли они UIcollectionView (возможно, нет, поскольку он работал на iOS5), но это тот вид, который я искал, кажется, что фотографии появляются справа.

4b9b3361

Ответ 1

Вы можете добиться этого эффекта независимо от пользовательского макета.

Код анимации должен находиться внутри collectionView:cellForItemAtIndexPath:

Когда ячейка вычеркнута, ее frame будет соответствовать тому, что указано в вашем макете. Вы можете сохранить его во временной переменной как окончательный frame для ячейки. Затем вы можете установить cell.frame в исходное положение за пределами экрана, а затем анимировать в желаемое конечное положение. Что-то вроде:

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

    UICollectionView *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];

    CGRect finalCellFrame = cell.frame;
    //check the scrolling direction to verify from which side of the screen the cell should come.
    CGPoint translation = [collectionView.panGestureRecognizer translationInView:collectionView.superview];
    if (translation.x > 0) {
        cell.frame = CGRectMake(finalCellFrame.origin.x - 1000, - 500.0f, 0, 0);
    } else {
        cell.frame = CGRectMake(finalCellFrame.origin.x + 1000, - 500.0f, 0, 0);
    }

    [UIView animateWithDuration:0.5f animations:^(void){
        cell.frame = finalCellFrame;
    }];

    return cell;
}

Приведенный выше код будет анимировать ячейки по горизонтали UICollectionView, начиная с верхней части экрана и с каждой стороны, в зависимости от направления прокрутки. Вы также можете проверить текущий indexPath на наличие анимированных ячеек с разных позиций на более сложных макетах, а также оживить другие свойства вместе с фреймом или применить преобразование.

Ответ 2

Вам нужно переопределить initialLayoutAttributesForAppearingItemAtIndexPath: в макете просмотра коллекции. Здесь вы можете установить любой атрибут в элементе атрибутов макета (включая преобразование), который будет анимирован к фактическим атрибутам после появления ячейки.

Если объект стандартных атрибутов макета не дает вам достаточно параметров, вы можете подклассифицировать его, добавить дополнительные атрибуты и переопределить applyLayoutAttributes: в своей ячейке, чтобы получить дополнительные свойства.

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

Чтобы преобразования, применяемые к ячейкам при прокрутке вниз по представлению коллекции, я бы посмотрел на их применение либо непосредственно в ячейку (в cellForItem...), либо в атрибутах макета, возможно, это свойство называется initialTransform. При применении атрибутов макета к ячейке вы должны проверить initialTransform, применить ее, затем установить ее на идентификатор, а затем запустить анимацию, чтобы перейти к преобразованию идентичности, поэтому она будет применяться только тогда, когда ячейка была сначала прокручена на экран. Я не реализовал ничего подобного, это просто предположение о том, как я это сделаю.

Ответ 3

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

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    static CGFloat duration = .5;
    static NSUInteger xOffset = 50;
    static NSUInteger yOffset = 200;
    if(scrollDirection == STAScrollDirectionDown && lastAnimatedIndex < indexPath.row)
    {
        cell.frame = CGRectMake(cell.frame.origin.x - xOffset, cell.frame.origin.y+yOffset, cell.frame.size.width, cell.frame.size.height);
        [UIView animateWithDuration:duration
                         animations:^{
            cell.frame = CGRectMake(cell.frame.origin.x + xOffset, cell.frame.origin.y - yOffset, cell.frame.size.width, cell.frame.size.height);
        } completion:^(BOOL finished) {
            lastAnimatedIndex = indexPath.row;
        }];
    }
}

Перед отображением ячейки мы назначаем смещение (и, возможно, поворот) для каждой ячейки, а затем возвращаем его назад к предыдущим настройкам.


немного более интересный пример:

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    CATransform3D rotation = CATransform3DMakeRotation( (90.0*M_PI)/180, .0, 0.5, 0.5);
    cell.contentView.alpha = 0.8;
    cell.contentView.layer.transform = rotation;
    cell.contentView.layer.anchorPoint = CGPointMake(0, 0.5);

    [UIView animateWithDuration:.5
                     animations:^{
                         cell.contentView.layer.transform = CATransform3DIdentity;
                         cell.contentView.alpha = 1;
                         cell.contentView.layer.shadowOffset = CGSizeMake(0, 0);
                     } completion:^(BOOL finished) {
                     }];
}