I have implemented customFlowLayout in my iOS App. And I have subclassed the targetContentOffsetForProposedContentOffset:withScrollingVelocity with
subclassing UICollectionViewFlowLayout. Now my issue is when user scrolls the collectionview it must scroll to only next index. Right now it scrolled randomly.
So anyone have any idea that how can I make the scroll restricts to only one item per scroll.
Following is my code.
#pragma mark - UICollectionViewLayout (UISubclassingHooks)
- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity {
CGSize collectionViewSize = self.collectionView.bounds.size;
CGFloat proposedContentOffsetCenterX = proposedContentOffset.x + collectionViewSize.width / 2;
CGRect proposedRect = CGRectMake(proposedContentOffset.x, 0, collectionViewSize.width, collectionViewSize.height);
UICollectionViewLayoutAttributes *candidateAttributes;
for (UICollectionViewLayoutAttributes *attributes in [self layoutAttributesForElementsInRect:proposedRect]) {
if (attributes.representedElementCategory != UICollectionElementCategoryCell) continue;
if (!candidateAttributes) {
candidateAttributes = attributes;
continue;
}
if (fabs(attributes.center.x - proposedContentOffsetCenterX) < fabs(candidateAttributes.center.x - proposedContentOffsetCenterX)) {
candidateAttributes = attributes;
}
}
proposedContentOffset.x = candidateAttributes.center.x - self.collectionView.bounds.size.width / 2;
CGFloat offset = proposedContentOffset.x - self.collectionView.contentOffset.x;
if ((velocity.x < 0 && offset > 0) || (velocity.x > 0 && offset < 0)) {
CGFloat pageWidth = self.itemSize.width + self.minimumLineSpacing;
proposedContentOffset.x += velocity.x > 0 ? pageWidth : -pageWidth;
}
return proposedContentOffset;
}
- (BOOL)shouldInvalidateLayoutForBoundsChange:(CGRect)newBounds {
return YES;
}
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
if (!self.scaleItems) return [super layoutAttributesForElementsInRect:rect];
NSArray *attributesArray = [[NSArray alloc] initWithArray:[super layoutAttributesForElementsInRect:rect] copyItems:YES];
CGRect visibleRect = (CGRect){self.collectionView.contentOffset, self.collectionView.bounds.size};
CGFloat visibleCenterX = CGRectGetMidX(visibleRect);
[attributesArray enumerateObjectsUsingBlock:^(UICollectionViewLayoutAttributes *attributes, NSUInteger idx, BOOL *stop) {
CGFloat distanceFromCenter = visibleCenterX - attributes.center.x;
CGFloat absDistanceFromCenter = MIN(ABS(distanceFromCenter), self.scalingOffset);
CGFloat scale = absDistanceFromCenter * (self.minimumScaleFactor - 1) / self.scalingOffset + 1;
attributes.transform3D = CATransform3DScale(CATransform3DIdentity, scale, scale, 1);
}];
return attributesArray;
}