I have created a UICollectionView
with cells containing several types of UIViewController
views as their contentView. I would like to cache the UIViewController
's which are not in use. I have tried creating a dictionary of the currently used UIViewController
's based on their indexPath, and a set of unused UIViewController
's to to be recycled UIViewController
's. Im noticing however that my UIViewControllers are not being deinitialized. I've based my implementation on these answers Add UIViewController to UICollectionViewCell and Make PageViewController reuse viewControllers like tableView.
Below is my implementation
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
addViewController(toCell: cell, at: indexPath, of: viewTypes[indexPath.item])
}
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
removeViewController(fromCell: cell, at: indexPath)
// cleanCachedViewControllers(index: indexPath.item)
}
func addViewController(toCell cell:UICollectionViewCell, at indexPath:IndexPath,of type:ViewControllerType){
var childViewController:UIViewController!
if let cvc = currentViewControllers[indexPath]{
childViewController = cvc
}else{
childViewController = TestViewController()
currentViewControllers[indexPath] = childViewController
}
self.addChild(childViewController)
childViewController.view.frame = cell.contentView.bounds
cell.contentView.addSubview(childViewController.view)
childViewController.didMove(toParent: self)
}
func removeViewController(fromCell cell:UICollectionViewCell, at indexPath:IndexPath){
guard let childViewController = currentViewControllers[indexPath] else {
return
}
print("remove view controller called")
childViewController.willMove(toParent: nil)
childViewController.view.removeFromSuperview()
childViewController.removeFromParent()
// currentViewControllers[indexPath] = nil
// currentViewControllers.removeValue(forKey: indexPath)
childViewController.view = nil
recycledViewControllers.insert(childViewController)
}
func getRecycledViewController(type:ViewControllerType)->UIViewController{
var unusedViewControllers = recycledViewControllers.filter { (viewController) -> Bool in
return viewController.isKind(of: type.type) && viewController.parent == nil
}
if let reusableViewController = unusedViewControllers.first{
recycledViewControllers.remove(reusableViewController)
return reusableViewController
}else{
let newViewController = type.initializeViewController()
// recycledViewControllers.append(newViewController)
return newViewController
}
}