Как прокручивать uicollectionviewcell программно в IOS?

у меня вертикаль UICollectionView С каждой клеткой, занимающей все self.view.frame Я могу легко пролистать вверх на страницу до следующей ячейки, но я хотел бы сделать то же самое с нажатием кнопки.

я пробовал использовать:

- (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated

и:

- (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated

они работают, но они временно "выбеливают" currentCell, чтобы представить nextCell, в то время как прокрутка показывает обе ячейки во время перехода.

в идеале я хотел бы использовать:

- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UICollectionViewScrollPosition)scrollPosition animated:(BOOL)animated

но я не знаю как получить доступ к nextCell это indexPath... Я пробовал:

NSIndexPath *nextIndexPath = [_collectionView indexPathForItemAtPoint:CGPointMake(25, (_collectionView.frame.size.height-25)*(_currentIndexRowForCellOnScreen+1))];

здесь _currentIndexRowForCellOnScreen - это indexPath.row на UICollectionViewпервое появление на экране в:

- (UICollectionViewCell*)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath

но когда я положил его в:

- (NSIndexPath *)indexPathForCell:(UICollectionViewCell *)cell

он возвращает NULL после первой ячейки и не анимируется....

любое направление было бы весьма признательно. Спасибо, что уделили мне время.

4 ответов


предполагая, что ваш collectionView содержит только 1 раздел, и учитывая, что каждый элемент занимает весь кадр, вы можете сделать что-то вроде этого;

  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];

вот версии 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)

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

@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 ответ

    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)
    }

измените положение прокрутки в соответствии с вашим требованием, а также количество строк, которые вы хотите пропустить (здесь я пропустил visibleItems.count)