Ответ 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);
}