【问题标题】:UICollectionView with full page cells VS UIScrollView with child view controllers带有整页单元格的 UICollectionView VS 带有子视图控制器的 UIScrollView
【发布时间】:2019-01-03 01:35:21
【问题描述】:

我正在尝试创建一个具有可滑动(类似 android 的标签)页面的 ViewController。这些页面本身将在其中包含滚动视图(垂直)和多个视图,这些视图将根据响应类型(每个页面的不同网络调用)动态添加。我不能使用 PageViewController,因为我希望页面只占屏幕的一半。

CollectionView 的问题 -

  • 如果单元格会被重用(或从内存中删除),我将如何维护单元格 UI 的状态并存储该数据(对于视图尤其困难,因为每个页面中可能有不同类型的视图)

ScrollView 的问题 -

  • 我担心如果所有页面视图控制器都在内存中,每个视图都在内存中,是否会出现内存问题

PS - 每个页面中的数据将是 4-10 个堆栈视图,每个堆栈视图包含 2-10 个图像/标签或只有一个集合视图

PSS - 选项卡总数不超过 10 个,最少为 1 个

【问题讨论】:

  • 你有没有想过使用 CoreData 来跟踪你想要的数据?
  • @Nickolans 跟踪数据并不是困难的部分,每个页面都会根据它们获得的不同类型的响应创建不同类型的视图,所以如果我使用集合视图,那么我将不得不删除滚动视图中的所有子视图并使用我存储的所有数据再次创建它们。
  • 使用 PageViewController ?.对于您的子视图控制器,您可以考虑不同的方法来处理内存问题,例如加载拇指图像,或者您可以使用 collectionview / tableview 而不是 stackview
  • @PrashantTukadiya 不能使用 PageViewController 因为我不希望页面占据整个屏幕(检查问题)。不能在页面内使用collectionview,因为每个块(堆栈)中的视图彼此非常不同。它们可能在不同页面中相似,但不在同一页面中。
  • 我认为您所说的 CollectionView 问题不是问题,而是您应该如何处理它。管理好您的数据(源)并根据您拥有的数据绘制您的 UI。单元重用的概念正是针对这些情况的。开发人员不应使用单元格(或其他 UI 元素)作为其数据存储。

标签: ios swift uiscrollview uicollectionview


【解决方案1】:

我用 collectionView 实现了它,因为它应该更有效地利用资源。但是我们需要缓存视图控制器的状态。这是一个例子

假设您有控制器A,其中包含collectionView 和您的子控制器的单元格。然后在单元格中为行

....
var childrenVC: [Int: UIViewController] = [:]
....
// cell for row
let cell: ChildControllerCell = collectionView.dequeueReusableCell(for: indexPath)
if let childController = childrenVC[indexPath.row] {
   cell.contentView.addSubview(childController.view)
   childController.view.frame = cell.contentView.frame
} else {
   let childViewController = ChildViewController()
   addChildViewController(childViewController)
   childViewController.didMove(toParentViewController: self)
   cell.contentView.addSubview(childController.view)
   childController.view.frame = cell.contentView.frame
   childrenVC[indexPath.row] = childViewController
   cell.childVC = childViewController
}
return cell
....
class ChildControllerCell: UICollectionViewCell {
     var childVC: UIViewController?
     override func prepareForReuse() {
        super.prepareForReuse()
        if !contentView.subviews.isEmpty {
            childVC?.willMove(toParentViewController: nil)
            childVC?.view.removeFromSuperview()
            childVC?.removeFromParentViewController()
        }
    }
}

【讨论】:

  • 因此,这与 scrollView 子控制器之间的唯一区别是,这会将子视图控制器从 deque 上的视图中移除并再次添加整个子控制器。它会让孩子 vc 一直在记忆中吗?只是从视图中删除 vc 实际上有任何帮助吗?
  • 您可以只保存数据而不是整个控制器,以减少内存使用。并在 cellForRow 上重新初始化它
  • 但实际上我不认为如果你只保存视图控制器会占用大量内存
  • 谢谢。我尝试了您的解决方案,内存差异最大为 15%,因此实施我想这是最好的选择。
  • 所以 collectionview 选项没有按预期工作。我面临的问题是细胞没有得到正确的重复使用(不知道为什么)。有时一个单元不会有任何子 vc,或者有时他们会有两个。我已经实现了 scrollView 选项并且没有显着增加内存,所以我认为这将是最好的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多