简体   繁体   English

UICollectionView内部的UiviewControllers

[英]UiviewControllers inside UICollectionViewCell

I have a UICollectionView inside a UIViewController. 我在UIViewController中有一个UICollectionView。 The collectionView holds an array of 8 identifiers of view controllers from the storyboard. collectionView包含来自故事板的8个视图控制器标识符的数组。 Each view controller in the array inherited from the UIViewController that holds the collectionView. 数组中的每个视图控制器都继承自保存collectionView的UIViewController。

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? 如何改进UICollectionView的性能? 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. 在这里的建议后,我已经将我的数组更改为持有视图控制器而不是标识符nsstring。

In the ViewDidLoad: 在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? 我的单元格没有显示视图任何想法为什么?

I was able to obtain smooth-scrolling performance of a collection of cells containing each its own child view controller by using a queue to keep and reuse a set number of instances. 通过使用队列来保持和重用一定数量的实例,我能够获得包含每个子视图控制器的单元集合的平滑滚动性能。

GitHub lists a number of reuse queue implementations; GitHub列出了许多重用队列实现; and, after a fairly thorough review of almost every one if them, I can confidently recommend this one: 并且,在对几乎每一个人进行相当彻底的审查之后,我可以自信地推荐这个:

https://github.com/acoomans/ACReuseQueue https://github.com/acoomans/ACReuseQueue

Per the ReadMe: A reuse queue is a way to quickly reuse objects when object allocation and initialization is time-consuming. 根据自述文件:重用队列是在对象分配和初始化耗时时快速重用对象的一种方法。

The reason your view is not showing is because you're not instantiating the child view controller from within the cell subclass, and not adding the view from within the cellForItemAtIndexPath. 您的视图未显示的原因是您没有从单元子类中实例化子视图控制器,也没有从cellForItemAtIndexPath中添加视图。 It's about scope, and you've got it backwards. 这是关于范围的,你已经倒退了。

The perfect set of instructions for adding a child view controllers to cells is provided here: 这里提供了向子单元添加子视图控制器的完美说明:

http://khanlou.com/2015/04/view-controllers-in-cells/ http://khanlou.com/2015/04/view-controllers-in-cells/

From the documentation of instantiateViewControllerWithIdentifier: - instantiateViewControllerWithIdentifier:的文档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 UIViewController s so they can be re-used, rather than storing the IDs and instantiating a new view controller every time tableView:cellForItemAtIndexPath: is called. 你最好存储一个UIViewController数组,这样它们就可以被重用,而不是每次调用tableView:cellForItemAtIndexPath:都存储ID并实例化一个新的视图控制器。

Also, since UICollectionViewCell s are re-used, it's not wise to keep adding subviews to the cell every time tableView:cellForItemAtIndexPath: is called. 此外,由于重新使用了UICollectionViewCell ,因此每次调用tableView:cellForItemAtIndexPath:时,继续向单元格添加子视图是tableView:cellForItemAtIndexPath: Instead, consider creating your own UICollectionViewCell subclass with a mainView property. 相反,请考虑使用mainView属性创建自己的UICollectionViewCell子类。 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. 在设置新的框架(或添加布局约束)并将其添加为子视图之前,您可以覆盖setMainView:从其超级视图中删除旧的mainView。

Also you should implement the methods for proper UIViewController containment . 您还应该实现适当的UIViewController包含的方法。

Update with Swift (add viewcontrollers in the collectionview's cell) 使用Swift更新(在collectionview的单元格中添加viewcontrollers)

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
    let cellContentVC = self.storyboard?.instantiateViewController(withIdentifier: screens[indexPath.row])
    cellContentVC?.view.frame = cell.bounds
    cell.addSubview(cellContentVC!.view)

    return cell

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM