如何以编程方式将 CollectionView 滚动到底部

Posted

技术标签:

【中文标题】如何以编程方式将 CollectionView 滚动到底部【英文标题】:How to Scroll CollectionView to bottom Programmatically 【发布时间】:2016-11-16 09:53:17 【问题描述】:

我使用这段代码来滚动集合视图:

let section = (self.collectionView?.numberOfSections)! - 1;
let item = (self.collectionView?.numberOfItems(inSection: section))! - 1;
let lastIndexPath = IndexPath(item: item, section: section);
self.collectionView?.scrollToItem(at: lastIndexPath, at: .bottom, animated: true);

但我得到错误:

* 由于未捕获的异常“NSRangeException”而终止应用程序,原因:“* -[__NSArrayM objectAtIndex:]:索引 1 超出范围 [0 .. 0]'

【问题讨论】:

【参考方案1】:

Swift 4+

extension UICollectionView 
    func scrollToLast() 
        guard numberOfSections > 0 else 
            return
        

        let lastSection = numberOfSections - 1

        guard numberOfItems(inSection: lastSection) > 0 else 
            return
        

        let lastItemIndexPath = IndexPath(item: numberOfItems(inSection: lastSection) - 1,
                                          section: lastSection)
        scrollToItem(at: lastItemIndexPath, at: .bottom, animated: true)
    

【讨论】:

应该在滚动之前为部分和项目索引添加如下边界检查以避免潜在的崩溃...让 lastSection = numberOfSections > 0 ? numberOfSections - 1 : 0 让 lastItemIndex = numberOfItems(inSection: lastSection) > 0 ? numberOfItems(inSection: lastSection) - 1 : 0 这适用于水平滚动的集合视图吗?【参考方案2】:
let lastItemIndex = NSIndexPath(forItem: data.count - 1, inSection: 0)
collectionView?.scrollToItemAtIndexPath(lastItemIndex, atScrollPosition: .Bottom, animated: true)

别忘了: - 在滚动位置:.Bottom - 你需要检查是data.count > 0 因为if data.count == 0 你会收到和你一样的错误

【讨论】:

【参考方案3】:

您也可以使用contentOffsetCollectionView 设置为底部动画

这是一个例子

let contentHeight: CGFloat = myCollectionView.contentSize.height
let heightAfterInserts: CGFloat = myCollectionView.frame.size.height - (myCollectionView.contentInset.top + myCollectionView.contentInset.bottom)
if contentHeight > heightAfterInserts 
    myCollectionView.setContentOffset(CGPoint(x: 0, y: myCollectionView.contentSize.height - myCollectionView.frame.size.height), animated: true) 

【讨论】:

嗨@Rajat 它可以工作,但由于单元格的高度是动态的,它不会将 collectionView 滚动到完全底部。 那么你需要得到确切的尺寸。 @PRINCE 你也可以试试这个myCollectionView.contentOffset = CGPoint(x: 0, y: myCollectionView.contentSize.height - myCollectionView.bounds.size.height) 实际上我正在创建一个聊天控制器,我通过collectionView.reloadData()向它加载了一些[消息](文本字符串数组);但是在我添加/附加新消息(字符串消息)到 [messages] 之后,我在执行此操作后调用了 collectionView.reloadData() 气泡大小缩小并且它不会滚动到底部。如果可以,请@Rajat 帮助我,我是 ios 新手 :( 你没有在你的问题中提到这些事情,创建一个新问题并将所有必要的信息用代码放在那里,因为我已经回答了你的问题 以编程方式将 CollectionView 滚动到底部【参考方案4】:
func scrollToItem(at: IndexPath, at: UICollectionViewScrollPosition, animated: Bool)

可以滚动集合视图内容,直到指定项目可见。如果项目不可见,您将收到类似 Terminating app due to uncaught exception 'NSRangeException' 的异常,原因:'...

【讨论】:

【参考方案5】:
var xItem:Int = 0
var currentIndex:NSIndexPath!
@IBOutlet weak var rateCollection: UICollectionView!

@IBAction func btnNextTapped(_ sender: UIButton)
    
        xItem = xItem+1
        if xItem != arrayRateModel.count
        
        currentIndex = NSIndexPath(item: xItem, section: 0)
        rateCollection.scrollToItem(at: currentIndex as IndexPath, at: .centeredHorizontally, animated: true)
           
    

【讨论】:

【参考方案6】:

目标-C

NSInteger noOfsections = [self numberOfSectionsInCollectionView:self.collectionView] - 1;
NSInteger noOFItems = [self collectionView:self.collectionView numberOfItemsInSection:noOfsections] - 1;
NSIndexPath *lastIndexPath = [NSIndexPath indexPathForItem:noOFItems inSection:noOfsections];
[self.collectionView scrollToItemAtIndexPath:lastIndexPath atScrollPosition:UICollectionViewScrollPositionBottom animated:YES];

【讨论】:

以上是关于如何以编程方式将 CollectionView 滚动到底部的主要内容,如果未能解决你的问题,请参考以下文章

以编程方式为 safeArea 调整 collectionView

Swift:如何以编程方式在 TableViewCell 中显示 CollectionView

如何以编程方式选择collectionview中的项目?

Swift 3:不能以编程方式在 Collectionview 标题上正确创建标签?

以编程方式为水平居中的元素提供偏移量

在 Swift 中以编程方式为 CollectionView 设置插图