如何在 IOS 中以编程方式滚动 UICollectionViewCell?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21540084/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 23:20:29  来源:igfitidea点击:

How to scroll UICollectionViewCell programmatically in IOS?

iosobjective-cuiscrollviewuicollectionviewuicollectionviewcell

提问by Rhotick

I have a vertical UICollectionViewwith each cell taking up the entire self.view.frameI can easily swipe upwards to page to the next cell, but I would like to do the same thing with the press of a button.

我有一个垂直UICollectionView的每个单元格占据整个self.view.frame我可以轻松地向上滑动以翻页到下一个单元格,但我想通过按一下按钮来做同样的事情。

I've tried using:

我试过使用:

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

And:

和:

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

They work but they temporarily "White-Out" the currentCell to present the nextCell, while the swiping shows both cells during the transition.

他们工作,但他们暂时“白化” currentCell 以呈现 nextCell,而在过渡期间滑动显示两个单元格。

Ideally I would like to use:

理想情况下,我想使用:

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

But I don't know how to access the nextCell's indexPath... I've tried:

但我不知道如何访问 nextCell indexPath......我试过:

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

Where _currentIndexRowForCellOnScreenis the indexPath.rowof the UICollectionView's first appearance on screen in:

哪里_currentIndexRowForCellOnScreenindexPath.row对的UICollectionView的屏幕上的首次亮相:

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

But when I put it into:

但是当我把它放进去:

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

it returns NULL after the first Cell, and does not animate....

它在第一个 Cell 之后返回 NULL,并且没有动画......

Any direction would be greatly appreciated. Thank you for your time.

任何方向将不胜感激。感谢您的时间。

回答by MDB983

Assuming your collectionView contains only 1 section, and given that each item occupies the whole frame then you could do something like this;

假设您的 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];

回答by Mr. Bean

By far this is the best approach i have encountered, the trick is to scroll to the frame which is containing next objects. Please refer the 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)
}

回答by Chathuranga Silva

Here are the Swift versions

这是 Swift 版本

Swift 2

斯威夫特 2

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, 4, 5

斯威夫特 3、4、5

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)

回答by Akila Wasala

Swift 4.1answer

斯威夫特 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)
    }

Change the scroll position according to your requirement and also the row count you want to skip (Here i have skipped visibleItems.count)

根据您的要求以及要跳过的行数更改滚动位置(这里我已跳过visibleItems.count

回答by Khodour.F

Swift 5:for example go + 1 next

Swift 5:例如 go + 1 next

var index:Int = self.collectionView.indexPathsForVisibleItems.first!.row
    index = index + 1

self.collectionView.scrollToItem(at: IndexPath(row: index, section: 0), at: UICollectionView.ScrollPosition.right, animated: true)