【问题标题】:How to scroll UICollectionViewCell programmatically in IOS?如何在 IOS 中以编程方式滚动 UICollectionViewCell?
【发布时间】:2014-02-27 16:33:56
【问题描述】:

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

我尝试过使用:

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

还有:

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

它们可以工作,但它们会暂时“白化”currentCell 以呈现下一个Cell,而在过渡期间滑动会显示两个单元格。

理想情况下我想使用:

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

其中_currentIndexRowForCellOnScreenUICollectionView 在屏幕上首次出现的indexPath.row

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

但是当我把它放进去的时候:

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

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

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

【问题讨论】:

    标签: ios objective-c uiscrollview uicollectionview uicollectionviewcell


    【解决方案1】:

    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)
    

    【讨论】:

      【解决方案2】:

      这里是 Swift 版本

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

      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)
      

      【讨论】:

        【解决方案3】:

        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

        【讨论】:

          【解决方案4】:

          到目前为止,这是我遇到的最好的方法,诀窍是滚动到包含下一个对象的框架。请参考代码

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

          【讨论】:

          • 移动完成后如何隐藏按钮。
          • 在目标c中做什么?? @Shivang Mishra
          【解决方案5】:

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

          【讨论】:

          • 我很惭愧我不知道 NSIndexPath 属性 .item 和 .section。除非您在 UIKit 框架参考中搜索它,否则它不会出现在 NSIndexPath 类参考中。但由于某种原因,在过渡期间我仍然得到相同的“white-Out”结果。谢谢你的回答,它确实回答了我最初的问题,所以我会给你信用。
          • 你不应该变白......我测试了它,我看到,正如预期的那样,滚动到正确的位置。话虽如此,我使用了一个现有的collectionView,其中有多个可见的单元格。我会查看您的单元格,确保您正在栅格化图层,否则您可能会在滚动时毫不犹豫地看到。
          • 请注意,indexPathsForVisibleItems 可能需要排序才能在索引 0 处获得最大数字
          • 我知道这是一个古老的讨论,但我也得到了“白化”。在我的例子中,我在 UICollectionView 的顶部有一个插图来显示它背后的一些东西。当您向上拖动 collectionview 时,它会在其前面滚动。这一切都完美而美丽。但是,只有当我以编程方式设置滚动位置时,我才会在插入的确切高度处将整个顶部变白。然后,当我用手稍微拖动集合时,它后面的视图再次可见。这个问题一直让我抓狂! :-( 还有其他人经历过这个并解决了吗?
          • 进一步测试表明,“white-out”是 UICollectionView 的背景颜色。当我将它设置为红色背景颜色时,它将是红色的。此外,在我以编程方式调整滚动位置之前,它的高度取决于滚动位置(但它当然在顶部达到最大值)。因此,就好像以编程方式设置滚动位置会调整集合视图的网格,而不是应该保持背景颜色的区域。棘手..!
          猜你喜欢
          • 2011-03-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-14
          相关资源
          最近更新 更多