我有 UIViewController (HomeController),其中有可水平滚动的 UICollectionView 。该集合视图包含2个单元格(该数字不是动态的,总是只有2个单元格)。单元格覆盖了所有屏幕。在每个单元格中,我都有一个子视图控制器,该控制器本身具有UICollectionView并垂直滚动。此内部collectonView的单元格包含大图像(覆盖整个单元格的大小)。 我在HomeController的 viewDidLoad 中设置子视图控制器,如下所示:
addChild(viewController)
viewController.didMove(toParent: self)
要将子控制器的视图作为子视图添加到我的单元格中,我在该单元格的类中具有 hostedView 属性:
class ContainerCell: UICollectionViewCell {
var hostedView: UIView? {
didSet {
guard let hostedView = hostedView else {
return
}
contentView.addSubview(hostedView)
hostedView.translatesAutoresizingMaskIntoConstraints = false
hostedView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true
hostedView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor).isActive = true
hostedView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true
hostedView.rightAnchor.constraint(equalTo: contentView.rightAnchor).isActive = true
}
}
}
我在 cellForItemAt 方法中设置的单元格的 hostedView :
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = containerView.dequeueReusableCell(withReuseIdentifier: ContainerCell.reuseIdentifier, for: indexPath) as! ContainerCell
cell.hostedView = childControllers[indexPath.item].view
return cell
}
childControllers 是一个数组,用于存储两个子视图控制器。
第一次启动应用程序时出现问题,我从第一个单元格滚动到第二个单元格,UI对滚动的反应有所延迟。它不会立即滚动,而是在我做出滚动手势后约0.5秒滚动。之后,来回滚动可以正常工作。据我所知,这是因为在启动时第二个单元格不可见,并且尚未运行 cellForItemAt 方法。当我滚动到该单元格时它将运行。这是完全由iOS的重用机制驱动的行为。但是似乎因为在具有大图像的单元中存在子控制器,所以需要分配过多的内存,因此会导致此延迟。在启动时,Xcode显示大约100mb的内存,滚动到第二个单元格后,它会增长到近200mb。 因此,即使我在 viewDidLoad 上初始化所有子控制器,它们的内存也仅在 cellForItemAt 阶段分配。 我想在初始阶段分配该内存,所以当我滚动时,它们已经在内存中了。这有点违反单元重用机制,但是我知道总是只有两个单元(和两个子控制器),所以我并不需要我的collectionView中的动态样式行为。
我尝试对单元格使用不同的复用标识符,并在 viewDidLoad 中而不是在 cellForItemAt 中将子控制器的视图分配给单元格的 hostedView 。没用。
有没有办法做到这一点?如果没有,如何以另一种方式处理呢? UI反应的延迟确实破坏了应用程序的用户体验。