UICollectionView с поддержкой предварительного просмотра и пейджинга

Я пытаюсь подражать тому, что Apple имеет, показывая результат поиска в App Store. (ссылка: http://searchengineland.com/apple-app-search-shows-only-one-result-at-a-time-133818)

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

Я попытался использовать UICollectionView и установить для clipSubviews значение NO, надеясь, что он покажет предыдущую страницу и следующую страницу, но как только ячейка уйдет с экрана, ячейка будет скрыта (удалена из иерархии представлений ) и не отображается. Я думаю, что это мухи шаблон UICollectionView (поведение UICollectionView). Любые идеи о том, что было бы возможно?

Приветствия,

Ренди Праната

Ответ 1

Проблема: UICollectionView как подкласс UIScrollView по существу оживляет свои границы шагами bounds.size. Хотя это может означать, что все, что вам нужно было сделать, это уменьшить границы при сохранении размера кадра, к сожалению, UICollectionView не будет отображать какие-либо ячейки за пределами его текущих границ... разрушая эффект предварительного просмотра.

Решение:

  • Создайте UICollectionView с пейджингом, установленным в НЕТ, и с нужным фреймом.
  • Создайте UICollectionViewCells, которые меньше, чем рамки/границы UICollectionView. На этом этапе часть кадра должна отображаться в кадре. Это должно быть видно перед выполнением других шагов ниже.
  • Добавьте collectionView.contentInset.left и right (предположим, что ваш макет горизонтальный), равный методу contentOffsetValue (как показано ниже для простоты), чтобы выровнять первую и последнюю ячейки до середины.
  • Создайте UICollectionViewFlowLayout, который переопределяет метод, который дает точку остановки следующим образом:

Так же:

-(CGFloat)contentOffsetValue
{
    return self.collectionView.bounds.size.width * 0.5f - self.itemSize.width * 0.5f;
}

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity
{

    static float EscapeVelocity = 0.5f; // otherwise snap back to the middle
    NSArray* layoutAttributesArray = [self layoutAttributesForElementsInRect:self.collectionView.bounds];

    if(layoutAttributesArray.count == 0)
        return proposedContentOffset;

    CGFloat currentBoundsCenterX = self.collectionView.contentOffset.x + self.collectionView.bounds.size.width * 0.5f;


    UICollectionViewLayoutAttributes* candidateNextLayoutAttributes = layoutAttributesArray.firstObject;


    for (UICollectionViewLayoutAttributes* layoutAttributes in layoutAttributesArray)
    {
        if ((layoutAttributes.representedElementCategory != UICollectionElementCategoryCell) ||
            (layoutAttributes == candidateNextLayoutAttributes)) // skip the first comparison
            continue;

        if(velocity.x > EscapeVelocity || velocity.x < -(EscapeVelocity))
        {
            if(velocity.x > EscapeVelocity && layoutAttributes.center.x > candidateNextLayoutAttributes.center.x)
            {

                candidateNextLayoutAttributes = layoutAttributes;
            }

            else if (velocity.x < -(EscapeVelocity) && layoutAttributes.center.x < candidateNextLayoutAttributes.center.x)
            {

                candidateNextLayoutAttributes = layoutAttributes;
            }
        }
        else
        {
            if(fabsf(currentBoundsCenterX - layoutAttributes.center.x) < fabsf(currentBoundsCenterX - candidateNextLayoutAttributes.center.x))
            {

                candidateNextLayoutAttributes = layoutAttributes;
            }
        }   
    }
    return CGPointMake(candidateNextLayoutAttributes.center.x - self.collectionView.bounds.size.width * 0.5f, proposedContentOffset.y);

}

Ответ 2

Я просто собрал образец проекта, который показывает, как вы могли это сделать. Я создал контейнерный вид, который на 100 точек шире, чем 320 точек для экрана. Затем я помещаю UICollectionView в этот контейнер. Это компенсирует все на 50 пунктов по обе стороны экрана.

Затем есть ячейка содержимого, которая просто имеет фон и ярлык, чтобы вы могли визуально идентифицировать происходящее. Слева и справа находятся пустые ячейки. В методе viewDidLoad для вставки содержимого установлены отрицательные значения слева и справа, чтобы теперь пустые ячейки отображались в виде. Вы можете настроить вставку по своему усмотрению.

Это очень похоже на поведение. Чтобы получить метку ниже, как в примере, вы можете просто проверить значение contentOffset, чтобы определить, какая ячейка находится в фокусе. Для этого вы должны использовать UIScrollViewDelegate, который является частью UICollectionView.

https://github.com/brennanMKE/Interfaces/tree/master/ListView

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