【问题标题】:Adjust collectionView.scrollToItem to consider inset?调整 collectionView.scrollToItem 以考虑插入?
【发布时间】:2018-06-26 04:15:45
【问题描述】:

我有时会像这样滚动到单元格的左侧:

collectionView.scrollToItem(
    at: IndexPath(row: 5, section: 0),
    at: .left, // TODO: Left ignores inset
    animated: true
)

这是在scrollToItem 实施之前的开始方式:

但是,当我尝试使用滚动到项目时,它会将单元格粘贴到边缘而不是考虑插入:

有没有一种简单的方法可以修复 collectionView.scrollToItem 以适应插入?

【问题讨论】:

  • .left 尝试 .bottom
  • 好主意,但不幸的是没有为我工作。我试过:“collectionView.scrollToItem(at:indexPath,at:[.bottom,.left],动画:true)”。我还尝试了不同的变体,例如 [.top, .left]、.bottom、.top、[.left, .bottom] 等。
  • 1.方向是垂直的还是水平的? 2. 你的细胞大小是多少?例如一次显示一项或两项或 n 个项目

标签: ios swift uicollectionview uicollectionviewlayout


【解决方案1】:

如果您将 inset 设置为 collectionView.contentInset 而不是 layout.sectionInset,则可以使用常规方法 collectionView.scrollToItem

【讨论】:

    【解决方案2】:

    目标-C

       /**
         Assumptions:
         1. Your collection view scrolls horizontally
         2. You are using UICollectionViewFlowLayout to layout you collection view
    
         @param indexPath IndexPath to scroll to
         @param animated Toggle animations
         */
        - (void)scrollToIndexPathPreservingLeftInset:(NSIndexPath *)indexPath animated:(BOOL)animated {
            UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)collectionView.collectionViewLayout;
            CGFloat sectionLeftInset = layout.sectionInset.left;
            UICollectionViewLayoutAttributes *attri = [layout layoutAttributesForItemAtIndexPath:indexPath];
            [collectionView setContentOffset:CGPointMake(attri.frame.origin.x - sectionLeftInset, 0) animated:animated];
        }
    

    Swift(未经语法验证)

    func scroll(toIndexPathPreservingLeftInset indexPath: IndexPath, animated: Bool) {
        let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
        let sectionLeftInset = layout.sectionInset.left
        var attri = layout.layoutAttributesForItem(at: aPath)
        collectionView.setContentOffset(CGPoint(x: (attri?.frame.origin.x - sectionLeftInset), y: 0), animated: animated)
    }
    

    Sample gif

    【讨论】:

      【解决方案3】:

      像这样为你的 collectionView 设置 conentInset 值:

      myCollectionView.contentInset = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10)
      

      然后添加这一行:

       if #available(iOS 11, *) {
                  self.myCollectionView.contentInsetAdjustmentBehavior =     .never
              }
      

      然后scrolltoItem 通过尊重 collectionView 的插图来工作。

      【讨论】:

      • 这是最新的正确答案(在 iOS 13 上测试)。在 iOS 11 之前collectionView.scrollToItem() 尊重collectionview insets,但在iOS 11 及更高版本上,我们需要设置contentInsetAdjustmentBehavior = .never
      【解决方案4】:

      由于每个单元格的框架都考虑了它的部分插图,因此您也可以使用 scrollRectToVisible(_:animated:)。

      let cell = collectionView.cellForItem(at: indexPath)!
      collectionView.scrollRectToVisible(cell.frame, animated: true)
      

      由于这是我们正在处理的帧,您可以微调该帧的一些所需偏移量。

      【讨论】:

      • 我认为这会起作用,但在我的情况下它根本没有任何作用。我相信它,因为它需要设置 contentSize 但我正在使用 itemSize。
      • cellForItem 要求单元格是可见的,因此如果您想滚动到不可见的索引路径将不起作用。
      • 在 iOS 15+ 中,这会起作用,因为 cellForItem 返回不可见的单元格。在 iOS-15 之前,不可见的单元格将返回 nil。
      【解决方案5】:

      如果其他人偶然发现滚动到水平集合视图的开头,在考虑部分插入时,我可以通过执行以下操作(在 Swift 5.2.4)。该解决方案利用了 UICollectionViews 是 UIScrollViews 的事实:

          (collectionView as UIScrollView).setContentOffset(.zero, animated: true)
      

      【讨论】:

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