当前位置: 首页 > 知识库问答 >
问题:

按单元格而非屏幕分页UICollectionView

董谦
2023-03-14

我有带水平滚动的UICollectionView,整个屏幕上总是有两个单元格并排显示。我需要滚动到单元格开始处。启用分页后,集合视图将滚动整个页面,即一次滚动2个单元格,然后停止。

我需要启用按单个单元格滚动,或按多个单元格滚动,并在单元格边缘停止。

我尝试子类化UICollectionViewFlowLayout并实现方法targetContentOffsetForProposedContentOffsetUICollectionViewFlowLayout子类的所有方法?谢谢

共有3个答案

郜光明
2023-03-14

以下是我在Swift 5中实现的基于垂直小区的寻呼:

override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {

    guard let collectionView = self.collectionView else {
        let latestOffset = super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity)
        return latestOffset
    }

    // Page height used for estimating and calculating paging.
    let pageHeight = self.itemSize.height + self.minimumLineSpacing

    // Make an estimation of the current page position.
    let approximatePage = collectionView.contentOffset.y/pageHeight

    // Determine the current page based on velocity.
    let currentPage = velocity.y == 0 ? round(approximatePage) : (velocity.y < 0.0 ? floor(approximatePage) : ceil(approximatePage))

    // Create custom flickVelocity.
    let flickVelocity = velocity.y * 0.3

    // Check how many pages the user flicked, if <= 1 then flickedPages should return 0.
    let flickedPages = (abs(round(flickVelocity)) <= 1) ? 0 : round(flickVelocity)

    let newVerticalOffset = ((currentPage + flickedPages) * pageHeight) - collectionView.contentInset.top

    return CGPoint(x: proposedContentOffset.x, y: newVerticalOffset)
}

一些注意事项:

  • 无故障
  • 将分页设置为 FALSE!(否则这将不起作用)
  • 允许您轻松设置自己的轻快感。
  • 如果在尝试此操作后某些内容仍然不起作用,请检查您的 itemSize 是否与项目的大小匹配,因为这通常是一个问题,尤其是在使用 collectionView(_:布局:sizeForItemAt:)时,请改为对 itemSize 使用自定义变量。
  • 当您设置自收集视图减速速率 = UIScrollView.减速速度时,此方法效果最佳。

这是一个水平版本(还没有彻底测试过,所以请原谅任何错误):

override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {

    guard let collectionView = self.collectionView else {
        let latestOffset = super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity)
        return latestOffset
    }

    // Page width used for estimating and calculating paging.
    let pageWidth = self.itemSize.width + self.minimumInteritemSpacing

    // Make an estimation of the current page position.
    let approximatePage = collectionView.contentOffset.x/pageWidth

    // Determine the current page based on velocity.
    let currentPage = velocity.x == 0 ? round(approximatePage) : (velocity.x < 0.0 ? floor(approximatePage) : ceil(approximatePage))

    // Create custom flickVelocity.
    let flickVelocity = velocity.x * 0.3

    // Check how many pages the user flicked, if <= 1 then flickedPages should return 0.
    let flickedPages = (abs(round(flickVelocity)) <= 1) ? 0 : round(flickVelocity)

    // Calculate newHorizontalOffset.
    let newHorizontalOffset = ((currentPage + flickedPages) * pageWidth) - collectionView.contentInset.left

    return CGPoint(x: newHorizontalOffset, y: proposedContentOffset.y)
}

这段代码基于我在个人项目中使用的代码,您可以在这里下载并运行示例目标来查看它。

松钟展
2023-03-14

只需重写方法:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
    *targetContentOffset = scrollView.contentOffset; // set acceleration to 0.0
    float pageWidth = (float)self.articlesCollectionView.bounds.size.width;
    int minSpace = 10;

    int cellToSwipe = (scrollView.contentOffset.x)/(pageWidth + minSpace) + 0.5; // cell width + min spacing for lines
    if (cellToSwipe < 0) {
        cellToSwipe = 0;
    } else if (cellToSwipe >= self.articles.count) {
        cellToSwipe = self.articles.count - 1;
    }
    [self.articlesCollectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForRow:cellToSwipe inSection:0] atScrollPosition:UICollectionViewScrollPositionLeft animated:YES];
}
穆宾白
2023-03-14

好的,所以我在这里找到了解决方案:targetContentOffsetForProposedContentOffset:withScrollingVelocity,但没有子类化UICollectionViewFlowLayout

我应该一开始就搜索< code > targetContentOffsetForProposedContentOffset 。

 类似资料:
  • 是否可以在另一个单元格的侧面添加一个单元格,垂直拆分屏幕?这在比较两个列表时似乎非常有用。 我不认为这个选项是现成的,所以我猜它需要一些额外的js?

  • 功能介绍 获取百度移动统计平台的全部屏幕分辨率列表 接口 https://openapi.baidu.com/rest/2.0/mtj/svc/config/getScreenList?access_token={ACCESS_TOKEN} 请求参数 参数名 类型 描述 样例 access_token string 用户登入后获取的token 1.a6b7dbd428f731035f771b8d

  • 我试图在工作表中附加一个单元格,例如单元格1A有一个边框并填充了灰色,我想插入一个字符串“你好”,但使用 销毁单元格格式,或者更确切地说,使单元格格式处于默认模式。我知道如何使用 方法,但在我的项目中,我用不同的单元格格式插入了许多不同的数据。我在谷歌上搜索了一下,没找到答案。还有别的办法解决我的问题吗? 来阐述我的问题。在1A中的工作表中,我有一个单元格格式单元格格式(用灰色填充,并有细边框)

  • 有没有办法绕过的正常行为及其屏幕外页限制?我的包含四个,每个片断包含一个图像。我遇到的问题是,在实例化时,会创建两个,这导致从catch同时下载/提取大约20个图像(每个片断大约10个)。是否可以禁用屏幕外页限制? 我的目标是只在选择时下载图像,或者只在用户悬停图像时下载图像。实现这一点的一种方法是使用侦听器并设置一个标志,该标志告诉是否允许下载图像。 我能想到的第二种方法是在上设置一个,并且只在

  • 我正在使用iText 5.5.4生成pdf。 我有一组行,这些行应该分组在一起,并有一个rowspan单元格来命名组。但是,在分页符上,“GRP”一词被分为“G”和“RP”。有没有一种方法可以让这个小组牢不可破,如果它不能放在当前的页面上,就可以在下一页上画出来? 我尝试了同时保持prowstogether和setBreakpoints,但没有得到一致的结果。 布局图像: 上述代码的PDF输出

  • 我有一个图像按钮在我的应用程序中的每一个活动。当图像按钮被按下时,我需要转到主屏幕。我正在使用代码 但是,当我在单击图像按钮后从主屏幕导航时,它应该会从它调用的地方转到相同的页面。 例如,我有Activity1、Activity2、Activity3、Activity4等…Activity1是首页,我会选择国家,然后去Activity2,然后去Activity3,等等,但如果我从Activity4