【问题标题】:UIcollectionView scrollToitemAtIndexPath does not work for non visible cellsUIcollectionView scrollToitemAtIndexPath 不适用于不可见的单元格
【发布时间】:2016-06-17 14:12:35
【问题描述】:

我是 iOS 和 Swift 的新手。

已经设法创建了一个 UICollectionView 与自定义 LayoutAttributes 和可重用的自定义单元格计算图像的高度。 这一切都很棒。工作正常,我可以手动滚动。都很好。

问题是我想以编程方式滚动到第 N 个 indexPath,但 scrollToItemAtIndexPath 似乎只对可见的有效。

所以我必须在 iphone 5S 上显示 9 张图像的 2 列图像。 图片总数为31张。

所以使用 collectionView 的 ScrollToItemAtIndexPath 最多可以工作到第 9 项。

但是,当我尝试以编程方式进一步滚动时,例如 12 日,它不起作用。 奇怪的是,如果手动滚动,然后调用代码,它就可以工作。 所以我调试了一下,发现只有前 9 个单元格是用高度计算的。 那会是问题吗?如果是这样,我怎样才能让它工作?

尝试了使用 didLayoutSubviews 和其他方法的建议,但没有奏效。

目前,我正在使用 didSelectItemAtIndexPath 集合视图函数以编程方式滚动。

编辑:

override func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    let item = self.collectionView(self.collectionView!, numberOfItemsInSection: 0) - 1
            let lastItemIndex = NSIndexPath(forItem: item, inSection: 0)
            self.collectionView?.scrollToItemAtIndexPath(lastItemIndex, atScrollPosition: UICollectionViewScrollPosition.CenteredVertically, animated: true)
}

即使我对索引路径的编号(例如 12)进行了硬编码,它仍然无法正常工作。 如果需要更多信息,请告诉我。

我错过了什么吗?

非常感谢。

【问题讨论】:

  • 请在您的问题中添加一些代码。你想什么时候滚动?您的代码如何滚动到给定的 NSIndexPath?
  • 您能否阐明“目前,我正在使用 didSelectItemAtIndexPath 集合视图函数以编程方式滚动”的意思。这可能与您的问题有关。另外,是的,请发布一些代码以提供帮助
  • @beeef 感谢您的快速回复,这里是滚动代码。
  • @DougMead 感谢您的回复。我有一个来自另一个 ViewController 的导航,它传递要在此 UICollectionView 中使用的对象数组,以及导航完成时导航到哪个索引的信息。然而,这并没有很好地工作,我通过使用 didSelectItemAtIndexPath 让它变得更简单了,我试图导航到特定的 indexPath。
  • 嗯。 didLayoutSubviews() 被多次调用(甚至可能在滚动时被重复调用),所以这可能不是最好的地方。另外,我注意到您将滚动位置设置为中心。为了清楚起见(如果你还不知道), UICollectionView 与空白作斗争。因此,例如,如果您尝试滚动到最后一项,它将不会滚动到中心。它将保持在底部。

标签: ios swift uicollectionview uicollectionviewcell


【解决方案1】:

你应该在viewDidAppear中调用scrollToItemAtIndexPath方法,这样cellForItemAtIndexPath已经被调用了。

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    collectionView.scrollToItemAtIndexPath(NSIndexPath(forRow: index, inSection: 0), atScrollPosition: .CenteredVertically, animated: false)

}

【讨论】:

    【解决方案2】:

    我最初赞成 Lilo 的回答,但我注意到将代码添加到 viewDidAppear 导致我的水平 collectionView 突然滚动/动画到我希望它滚动到的索引。

    正确的做法is from this answer

    在viewWillAppear中,在调用collectionView.scrollToItem之前,先调用view.layoutIfNeeded(),场景出现时不会出现突然的视觉滚动。

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
    
        view.layoutIfNeeded() // call this before you call scrollToItem
    
        let lastItemIndex = NSIndexPath(forItem: item, inSection: 0)
        collectionView.scrollToItem(at: lastItemPath, at: .centeredHorizontally, animated: false)
    
    }
    

    【讨论】:

    • 不幸的是,滚动在 viewWillAppear 中不起作用。即使我事先调用 view.layoutIfNeeded() 。但是,我的代码库是 Objective C。这有关系吗?
    • @ErayAlparslan 它在 Swift 中对我有用,我不能在 Obj-C 上发言。尝试 viewDidLayoutSubviews 但使用 bool 来确保它运行一次。对于 ex var didLayoutSubviewsRun = false 然后在 viewDidLayoutSubviews 如果它是 false,将其更改为 true 然后添加 cv.scrollToItem 之后
    • 感谢您的回复。一旦我在主线程中滚动它,它就对我有用。
    • 如果答案成功,它会帮助其他人。干杯!
    【解决方案3】:

    当我尝试滚动到不可见的单元格并在 indexPath 处获取该单元格时,这对我有帮助:

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        collectionView.scrollToItem(at: indexPath, at: .centeredVertically, animated: false)
        view.layoutIfNeeded()
        // here you can get a cell
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多