【问题标题】:UITableView + UICollectionView + UITableView sizing issueUITableView + UICollectionView + UITableView 大小问题
【发布时间】:2021-11-30 12:01:00
【问题描述】:

下面的图片代表我的要求:

在此图像中,黄色UITableView 将包含不同UITableViewCell 项目的列表。在其中一个UITableViewCell 中,它具有UICollectionView 及其UICollectionViewCell 项目列表,并且UICollectionView 的滚动方向设置为水平

每个UICollectionViewCell 将有一个UITableView(以红色突出显示),并将具有UITableViewCell(以玫瑰色突出显示)项目的列表。在这里,UITableViewCell(以玫瑰色突出显示)项目可以折叠/展开。每当单元格折叠/展开时,都会自动处理红色表格的内容大小。但是,每当红色表格的内容大小增加时,collectionview 的大小就不会增加。

我已经为这些 UI 元素添加了所有相关的约束。但是,展开 tableview 单元格时,collectionview 的内容大小或框架不会扩大。

为了更好地理解这里,我将分解视图的设计方式:

  1. 黄色 tableview 嵌入在 UIViewController 中,它将有一个简单的 UITableViewCell 没有自定义类
  2. 以编程方式将UICollectionView 添加到单元格中。这个UICollectionView 被放置在一个xib 文件中,它已经嵌入到UIView
  3. UICollectionViewCell 已在一个 xib 中创建,其中将包含 UITableView 元素。
  4. 另外,UITableViewCell 有自己的 xib 可供参考,这是可以展开/折叠的单元格

我尝试修改intrinsicContentSize 属性以修改UICollectionView 属性的高度,它在展开时嵌入到UIView 元素中。请参考CardView.swift

CardView.swift

我知道设计有点复杂。但是,我在这里缺少什么?

【问题讨论】:

    标签: ios swift uitableview uicollectionview uicollectionviewcell


    【解决方案1】:

    根据您对图片的要求,我刚刚创建了一个示例项目here

    我没有使用单独的 Xib。但是,我能够实现您的要求。 您可能需要根据您的应用业务逻辑更好地处理最内层 tableView 的重新加载。

    这是我已经实现的:

    1. 最顶层的视图控制器有一个父表视图。
    2. 此表格视图单元格包含一个子集合视图。
    3. 子集合视图单元由一个大子表视图组成。
    4. 大子表视图对应于问题中以玫瑰色突出显示的表视图。
    5. 要回答关于集合视图未扩展的问题:为了在点击孙表视图单元格时展开子集合视图,我通过增加包含集合视图的单元格的行高来重新加载父表视图。因此您不必担心在自动布局中调整约束
    6. 如果您想在子集合视图单元格中添加其他内容,您可以将高度约束添加到具有低优先级的大子表视图,并在需要扩展大子表视图中的内容时修改它.
    7. 如果您想达到第 6 点,正如@Ramy Al Zuhouri 所建议的那样,您可能需要在collectionView.reloadData() 之前调用:collectionView.performBatchUpdates 以扩大单元格大小

    请参阅下面的视频以更好地理解

    【讨论】:

    • 您的第 6 点和第 7 点效果非常好。我应该以低优先级保持高度限制来实现这一点。
    【解决方案2】:

    这不一定能解决您的问题,但有时是强制集合视图使其布局无效并重新计算其大小的问题。我曾经收到一位 Apple 工程师对 TSI 的答复:

    所以这是强制可重用容器(Collection || Table)使其布局无效的老式方法。您甚至可以只调用无效布局。系统中的 AutoLayout 和动画有一些奇怪之处,有时会使系统进入奇怪的状态。如果我们对容器进行上述操作,可以使其布局无效并进行更新,而无需重新计算+合并动画。总而言之,如果您需要根据布局内容(不一定是数据源更改)强制更新,使用 nil 参数调用 performBatchUpdates 会很有用。

    这看起来像是一个需要谨慎使用的 hack,但值得一试。每当您需要重新计算集合视图的单元格大小以扩大或缩小时,您都可以这样做:

    UIView.setAnimationsEnabled(false)
    collectionView.performBatchUpdates(nil, completion: nil)
    UIView.setAnimationsEnabled(true)
    collectionView.reloadData()
    

    这会强制重新加载,并且 UIKit 能够在您更新高度后重新计算单元格的高度。如何?就我而言,我是通过更新高度约束来完成的,但是有多种方法可以做到这一点。然而,当重新加载发生时,集合视图应该知道新的单元格高度。

    【讨论】:

    • 只有当我改变内部 tableview 的高度时,这个 bactch 更新才真正运作良好。
    • @Praveenkumar 我的错误,我理所当然地迈出了一步。确实 reload 本身是不够的,UIKit 也应该知道新的高度。要么是因为您明确设置它,要么是通过更新的约束。我在回答中添加了更多细节。
    【解决方案3】:

    对此的好方法,您必须在 tableViewHeader 中添加 collectionView 那么每当您向上滚动 tableView 时,您的 collectionView 部分也会向上滚动

    要在特定索引上加载单元格,请按照以下步骤操作:

    if(indexpath.row == 0){
    //load first tableView cell with collection view 
    }
    else if (indexpath.row == 1){
    //load second tableView cell with collection view
    }
    else{
    //load table view cell here
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-11-18
      • 2019-07-18
      • 1970-01-01
      • 1970-01-01
      • 2014-12-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多