2016-03-14 1 views
4

Я внедрил customFlowLayout в мое приложение для iOS. И я подклассифицировал targetContentOffsetForProposedContentOffset:withScrollingVelocity с подклассом UICollectionViewFlowLayout. Теперь моя проблема - когда пользователь прокручивает collectionview, он должен прокручивать только следующий индекс. Прямо сейчас он прокручивался случайным образом.
Итак, у кого-нибудь есть идея, что я могу сделать ограничение прокрутки только одним элементом для прокрутки.
Ниже приведен мой код.UICollectionView с CustomFlowLayout Как ограничить прокрутку только одной страницы на прокрутку?

#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; 
} 
+3

U не использовал пейджинг для этой цели? –

+0

Я использовал пейджинг, но все еще его nt working/ –

ответ

1

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

То, что вы хотите, может быть не очень удобно использовать, когда пользователь пытается прокрутить быстро ...

Во всяком случае, чтобы получить то, что вы хотите, вы в принципе хотите использовать proposedContentOffset только для определения направления прокрутки (это больше или меньше, чем текущее смещение содержимого).

Теперь, когда у вас есть, вы можете получить атрибуты макета для элементов на следующей или предыдущей странице (вместо текущего кода, который может получить атрибуты на многие страницы). Это текущее смещение + или - ширина представления.

Остальная часть вашего кода остается неизменной. Не обращая внимания на направление прокрутки, это что-то вроде:

- (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity 
{ 
    CGSize collectionViewSize = self.collectionView.bounds.size; 
    CGFloat width = collectionViewSize.width; 
    CGFloat halfWidth = width * 0.5; 

    CGFloat direction = (proposedContentOffset.x > self.collectionView.contentOffset.x ? 1 : 0); 
    CGFloat pageOffsetX = 250.0 * floor(self.collectionView.contentOffset.x/250.0); 
    CGFloat proposedContentOffsetCenterX = pageOffsetX + (width * direction); 
    CGRect proposedRect = CGRectMake(proposedContentOffsetCenterX, 0, collectionViewSize.width, collectionViewSize.height); 

    UICollectionViewLayoutAttributes *candidateAttributes; 

    for (UICollectionViewLayoutAttributes *attributes in [self layoutAttributesForElementsInRect:proposedRect]) { 
     if (attributes.representedElementCategory != UICollectionElementCategoryCell) continue; 

     candidateAttributes = attributes; 
     break; 
    } 

    proposedContentOffset.x = candidateAttributes.center.x - halfWidth; 

//  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; 
} 

Я закомментировал часть в нижней части, как это не должно требоваться для первоначальной версии. Сначала протестируйте его с помощью простой версии, а затем уточните, если вам нужно больше контроля в случаях краев.

+0

он не работает. Скажите, пожалуйста, коротко скажите мне? –

+0

, каким образом он не работает (помните, я набрал вышеуказанный код на своем iPad) - главное, чтобы не использовать предлагаемую точку остановки и использовать текущее смещение содержимого – Wain

+0

, делая это моя ячейка не центрируется , –

Смежные вопросы