I have UIViewController(HomeController) with horizontally scrollable UICollectionView in it. This collection view contains 2 cells (the number is not dynamic, there will be always only 2 cells). The cell covers all the screen. In each cell I have a child view controller, which has a UICollectionView itself and scrolls vertically. The cells of this inner collectonView contain big images (cover whole size of a cell). I set up my child view controllers in HomeController's viewDidLoad like this:
addChild(viewController)
viewController.didMove(toParent: self)
To add child controller's view as a subview to my cells I have hostedView property in the cell's class:
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
}
}
}
This hostedView of the cell I set up in cellForItemAt method:
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 is an array where I store my two child view controllers.
The problem there is when app is launched for the first time and I scroll from the first cell to the second there is a delay in UI's reaction to the scroll. It scrolls not immediately but about 0.5 sec later after I do a scroll gesture. After that back and forth scrolls work fine. As far as I can tell this happens because at the launch the 2nd cell is not visible and cellForItemAt method for it hasn't been run yet. It runs when I scroll to this cell. This is completely fine behavior driven by iOS' reuse mechanism. But seems like because there is child controller in the cell with big images in it there is too much memory needed to be allocated so it causes this delay. At the launch Xcode shows about 100mb in memory, after a scroll to the second cell it grows to almost 200mb. So even that I initialize all child controllers at viewDidLoad, the memory for them allocates only at cellForItemAt stage. I would like to allocate that memory at the initial stage, so when I scroll they would be in the memory already. It kind of goes against cell reuse mechanism, but I know that there will always be only two cell (and two child controllers), so I don't really need that dynamic style behavior from my collectionView.
I tried to use different reuseIdentifiers for cells, and assign child controller's view to cell's hostedView in viewDidLoad, not in cellForItemAt, but it hasn't worked.
Is there any way to do that? And if there is not, how to approach this another way? This delay in UI reaction is really ruining user experience of the app.