【问题标题】:UICollectionView to read from left to right with multiple rowsUICollectionView 从左到右读取多行
【发布时间】:2018-11-15 16:12:45
【问题描述】:

我正在创建一个UICollectionView,它启用了分页并从左到右滚动。我正在使用 NSFetchedResultsController 从 CoreData 检索结果,这意味着它使用集合视图部分而不是行。集合视图有 2 行,因此如下图所示(顺序依次为顶行、底行、顶行、底行等):

但是,我需要像以下 2 个屏幕截图一样从左到右读取集合视图:

您能否建议我如何在 Swift 中执行此操作?

【问题讨论】:

  • 所以 b 有 IndexPath(row: 1, section: 0) ?
  • @marosoaie 我已经用更多信息编辑了我的问题。但基本上我使用的是使用集合视图部分的 NSFetchedResultsController。
  • 那么也许您需要对数据进行排序,使其与您想要达到的顺序相匹配?
  • iirc 流式布局使单元格从左到右移动,当没有更多空间时,下一行开始,依此类推,所以你只能通过设置排序来获得它获取请求上的描述符
  • 你能用 a、b、c、d、e、f、g 等代替 IndexPath 值吗?最后的截图也是第2页的预览吗?

标签: ios swift uicollectionview uicollectionviewlayout


【解决方案1】:

我会这样做:

1) 以与您现在相同的方式对数据进行排序,以便您的集合视图如下所示:

---------
|0|2|4|6|
---------
|1|3|5|7|
---------

2) 在您的集合视图数据源的 cellForIndexPath 方法中,返回正确的元素,以便您的集合视图变成这样:

---------
|0|1|2|3|
---------
|4|5|6|7|
---------

为此,您可以使用以下逻辑:

public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    var elementIndex: Int!
    if indexPath.row % 2 == 0 {
        // 0 / 2 = 0
        // 2 / 2 = 1
        // 4 / 2 = 2, etc
        elementIndex = indexPath.row / 2
    }
    else {
        // (1 / 2) + round(8.0 / 2.0) = 4
        // (3 / 2) + round(8.0 / 2.0) = 5
        // (5 / 2) + round(8.0 / 2.0) = 6, etc
        elementIndex = (indexPath.row / 2) + Int(round(Double(elements.count) / 2.0))
    }

    // Dequeue your cell
    // let cell = ...

    cell.element = elements[elementIndex]
    return cell
}

基本上这应该以正确的顺序返回您的元素。

【讨论】:

  • 您好,感谢您的帮助。您的第二个解决方案一半有效,唯一的问题是我在集合视图中有多个页面,并且进行了上述更改,集合视图现在看起来像 0-1-2-3 4-5-6-7 8-9-顶行 10-11,底行 12-13-14-15 16-17-18-19 20-21-22-23
  • 哦!我刚刚意识到:你想在第一页的第一行走 0-1-2-3,然后在第一页的第二行走 4-5-6-7,然后对第二页做同样的事情:第 1 行 8-9-10-11 和第 2 页第 2 行 12-13-14-15... 是这样吗?如果是这样,是的,我的解决方案没有这样做:(
  • 是的,这就是我需要的阅读方式!啊,不用担心,感谢您的帮助!
  • 嗨@AdamAltinkaya,你的问题已经回答了吗?,你也可以分享一下吗?因为我有同样的情况
【解决方案2】:

首先,我认为如果您提供一个当前如何对单元格进行分区的示例(例如,第 0 节:a、b、c、d第 1 节:e、f , ...) 以及您希望不同部分的显示/布局方式。


我建议创建一个自定义 UICollectionViewLayout 子类。

在 prepareLayout 方法中,您应该计算并缓存每个单元格的 UICollectionViewLayoutAttributes。

创建变量:

let xOffset = 0.0 // leftContentInset within collectionView.bounds
let yOffsetRow0 = 0.0  // y offset of first row within collectionView.bounds
let yOffsetRow1 = 50.0 // y offset of second row within collectionView.bounds
var currentXOffset : CGFloat = xOffset
var currentPage : Int = 0
  1. 计算帧数,直到第一行填充到屏幕右边缘(CGRect(currentXOffset, yOffsetRow0, cellWidth, cellHeight),增加 currentXOffset)
  2. 重置currentXOffset = xOffset
  3. 重复 1. 第二行使用 yOffsetRow1
  4. 递增currentPage += 1
  5. 重置currentXOffset = xOffset + (collectionView.frame.width * currentPage) // 下一页
  6. 重复步骤 1-5,直到计算出所有单元格的布局

【讨论】:

    【解决方案3】:

    正如你所说,你需要 1. 启用分页 2.从左到右滚动 3. 多个部分。

    您到底想要设计什么有点令人困惑。如果能分享合适的UI截图就更好了。

    据我了解您的问题。

    let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
    

    检查您是否将水平布局分配给您的 collectionView。

    【讨论】:

      猜你喜欢
      • 2018-01-03
      • 2021-02-09
      • 2014-10-03
      • 1970-01-01
      • 1970-01-01
      • 2012-11-26
      • 2019-10-22
      • 2015-06-18
      • 1970-01-01
      相关资源
      最近更新 更多