J'ai une UICollectionView
verticale avec chaque cellule reprenant l'intégralité du self.view.frame
. Je peux facilement glisser vers le haut pour passer d'une cellule à l'autre, mais j'aimerais faire la même chose en appuyant sur un bouton.
J'ai essayé d'utiliser:
- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated
Et:
- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated
Ils fonctionnent, mais ils «masquent» temporairement la currentCell pour présenter la nextCell, tandis que le balayage affiche les deux cellules pendant la transition.
Idéalement, j'aimerais utiliser:
- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated
Mais je ne sais pas comment accéder à la variable indexPath
... de nextCell. J'ai essayé:
NSIndexPath *nextIndexPath = [_collectionView indexPathForItemAtPoint:CGPointMake(25, (_collectionView.frame.size.height-25)*(_currentIndexRowForCellOnScreen+1))];
Où _currentIndexRowForCellOnScreen
est le indexPath.row
de la première apparition de la UICollectionView
à:
- (UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
Mais quand je le mets dans:
- (NSIndexPath *)indexPathForCell:(UICollectionViewCell *)cell
il retourne NULL après la première cellule et n'anime pas ....
Toute direction serait grandement appréciée. Merci pour votre temps.
En supposant que votre collectionView ne contient qu'une section et que chaque élément occupe l'intégralité du cadre, vous pouvez procéder de la sorte.
NSArray *visibleItems = [self.collectionView indexPathsForVisibleItems];
NSIndexPath *currentItem = [visibleItems objectAtIndex:0];
NSIndexPath *nextItem = [NSIndexPath indexPathForItem:currentItem.item + 1 inSection:currentItem.section];
[self.collectionView scrollToItemAtIndexPath:nextItem atScrollPosition:UICollectionViewScrollPositionTop animated:YES];
Voici les versions de Swift
Swift 2.x:
let visibleItems: NSArray = self.collectionView.indexPathsForVisibleItems()
let currentItem: NSIndexPath = visibleItems.objectAtIndex(0) as! NSIndexPath
let nextItem: NSIndexPath = NSIndexPath(forRow: currentItem.item + 1, inSection: 0)
self.collectionView.scrollToItemAtIndexPath(nextItem, atScrollPosition: .Top, animated: true)
Swift 3.x
let visibleItems: NSArray = self.collectionView.indexPathsForVisibleItems as NSArray
let currentItem: IndexPath = visibleItems.object(at: 0) as! IndexPath
let nextItem: IndexPath = IndexPath(item: currentItem.item + 1, section: 0)
self.collectionView.scrollToItem(at: nextItem, at: .top, animated: true)
De loin c'est la meilleure approche que j'ai rencontrée, l'astuce consiste à faire défiler jusqu'au cadre qui contient les objets suivants. S'il vous plaît se référer le code
@IBAction func actionPreviousFriends(_ sender: Any) {
let collectionBounds = self.collectionView.bounds
let contentOffset = CGFloat(floor(self.collectionView.contentOffset.x - collectionBounds.size.width))
self.moveToFrame(contentOffset: contentOffset)
}
/* -------------- display next friends action ----------------*/
@IBAction func actionNextFriends(_ sender: Any) {
let collectionBounds = self.collectionView.bounds
let contentOffset = CGFloat(floor(self.collectionView.contentOffset.x + collectionBounds.size.width))
self.moveToFrame(contentOffset: contentOffset)
}
func moveToFrame(contentOffset : CGFloat) {
let frame: CGRect = CGRect(x : contentOffset ,y : self.collectionView.contentOffset.y ,width : self.collectionView.frame.width,height : self.collectionView.frame.height)
self.collectionView.scrollRectToVisible(frame, animated: true)
}
Swift 4.1 réponse
let visibleItems = self.collectionView.indexPathsForVisibleItems
let currentItem = visibleItems.first
let nextRow = (currentItem?.row)! + visibleItems.count
if nextRow < elementArray.count {
let nextIndexPath = IndexPath.init(row: nextRow, section: (currentItem?.section)!)
self.collectionView.scrollToItem(at: nextIndexPath, at: UICollectionViewScrollPosition.left, animated: true)
} else {
let nextIndexPath = IndexPath.init(row: 0, section: (currentItem?.section)!)
self.collectionView.scrollToItem(at: nextIndexPath, at: UICollectionViewScrollPosition.right, animated: true)
}
Modifiez la position de défilement en fonction de vos besoins et du nombre de lignes que vous souhaitez ignorer (ici, j'ai sauté visibleItems.count
).