Search code examples
iosobjective-cuiviewcontrolleruicollectionviewuicollectionviewcell

UiviewControllers inside UICollectionViewCell


I have a UICollectionView inside a UIViewController. The collectionView holds an array of 8 identifiers of view controllers from the storyboard. Each view controller in the array inherited from the UIViewController that holds the collectionView.

Here is the code:

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return _contentPageRestorationIDs.count;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];

BaseContentViewController *contentViewController = (BaseContentViewController *)[self.storyboard instantiateViewControllerWithIdentifier:self.contentPageRestorationIDs[indexPath.row]];

// Set any data needed by the VC here
contentViewController.rootViewController = self;
contentViewController.view.frame = cell.bounds;
[cell addSubview:contentViewController.view];

return cell;
}

So my problem is that my collection view swipe performance is really slow. How can i improve the UICollectionView's performance? Are my view controllers inside the cell are "killed" when they are not on display?

Edit:

after the advice here i have changed my array to holding a view controllers instead of identifiers nsstring.

In the ViewDidLoad:

_collectionView.delegate=self;
_collectionView.dataSource=self;
PRzeroVC  *zeroVC    = [[PRzeroVC alloc]init];
PRoneVC   *oneVC     = [[PRoneVC alloc]init];
PRtwoVC   *twoVC     = [[PRtwoVC alloc]init];
PRthreeVC *threeVC   = [[PRthreeVC alloc]init];
PRfourVC  *fourVC    = [[PRfourVC alloc]init];
PRfiveVC  *fiveVC    = [[PRfiveVC alloc]init];

_base           = [[BaseContentViewController alloc]init];

_pages = [[NSArray alloc]initWithObjects:zeroVC,oneVC,twoVC,threeVC,fourVC,fiveVC, nil];

[_collectionView reloadData];



- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
UICollectionViewCell *cell = (UICollectionViewCell *)[collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath];

cell.layer.shouldRasterize = YES;
cell.layer.rasterizationScale = [UIScreen mainScreen].scale;
_base = (BaseContentViewController *)_pages[indexPath.row];

_base.rootViewController = self;
_base.view.frame = cell.bounds;
[cell addSubview:_base.view];

return cell;
}

My cell is not displaying the view Any idea why?


Solution

  • From the documentation of instantiateViewControllerWithIdentifier: -

    This method creates a new instance of the specified view controller each time you call it

    You would be better to store an array of UIViewControllers so they can be re-used, rather than storing the IDs and instantiating a new view controller every time tableView:cellForItemAtIndexPath: is called.

    Also, since UICollectionViewCells are re-used, it's not wise to keep adding subviews to the cell every time tableView:cellForItemAtIndexPath: is called. Instead, consider creating your own UICollectionViewCell subclass with a mainView property. You could override setMainView: to remove the old mainView from its superview, before setting the new one's frame (or adding layout constraints) and adding it as a subview.

    Also you should implement the methods for proper UIViewController containment.