Note that there are some explanatory texts on larger screens.

plurals
  1. POUICollectionView Performance Problems on performBatchUpdates
    primarykey
    data
    text
    <p>We are trying to set up a UICollectionView with a custom layout. The content of each CollectionViewCell will be an image. Over all there will be several thousand images and about 140-150 being visible at one certain time. On an action event potentially all cells will be reorganized in position and size. The goal is to animate all the moving events currently using the performBatchUpdates method. This causes a huge delay time before everything gets animated.</p> <p>This far we found out that internally the method layoutAttributesForItemAtIndexPath is called for every single cell (several thousand in total). Additionally, the method cellForItemAtIndexPath is called for more cells than can actually be displayed on the screen.</p> <p>Are there any possibilities to enhance the performance of the animation?</p> <hr> <p>The default UICollectionViewFlowLayout can't really offer the kind of design we want to realize in the app. Here's some of our code:</p> <pre><code>-(UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { RPDataModel *dm = [RPDataModel sharedInstance]; //Singleton holding some global information NSArray *plistArray = dm.plistArray; //Array containing the contents of the cells NSDictionary *dic = plistArray[[indexPath item]]; RPCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"CELL" forIndexPath:indexPath]; cell.label.text = [NSString stringWithFormat:@"%@",dic[@"name"]]; cell.layer.borderColor = nil; cell.layer.borderWidth = 0.0f; [cell loadAndSetImageInBackgroundWithLocalFilePath:dic[@"path"]]; //custom method realizing asynchronous loading of the image inside of each cell return cell; } </code></pre> <p>The layoutAttributesForElementsInRect iterates over all elements setting layoutAttributes for allthe elements within the rect. The for-statement breaks on the first cell being past the borders defined by the bottom-right corner of the rect:</p> <pre><code>-(NSArray*)layoutAttributesForElementsInRect:(CGRect)rect { NSMutableArray* attributes = [NSMutableArray array]; RPDataModel *dm = [RPDataModel sharedInstance]; for (int i = 0; i &lt; dm.cellCount; i++) { CGRect cellRect = [self.rp getCell:i]; //self.rp = custom object offering methods to get information about cells; the getCell method returns the rect of a single cell if (CGRectIntersectsRect(rect, cellRect)) { NSIndexPath *indexPath = [NSIndexPath indexPathForItem:[dm.relevanceArray[i][@"product"] intValue] inSection:0]; UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; attribute.size = cellRect.size; attribute.center = CGPointMake(cellRect.origin.x + attribute.size.width / 2, cellRect.origin.y + attribute.size.height / 2); [attributes addObject:attribute]; } else if (cellRect.origin.x &gt; rect.origin.x + rect.size.width &amp;&amp; cellRect.origin.y &gt; rect.origin.y + rect.size.height) { break; } } return attributes; } </code></pre> <p>On Layout changes the results are pretty much the same no matter if the number of cells being defined in the layoutAttributesForElementsInRect is limited or not .. Either the system gets the layout attributes for all cells in there if it isn't limited or it calls the layoutAttributesForElementAtIndexPath method for all the missing cells if it is limited. Overall the attributes for every single cell is being used somehow.</p> <pre><code>-(UICollectionViewLayoutAttributes*)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath { RPDataModel *dm = [RPDataModel sharedInstance]; UICollectionViewLayoutAttributes *attribute = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; CGRect cellRect = [self.rp getCell:[dm.indexDictionary[@(indexPath.item)] intValue]]; attribute.size = cellRect.size; attribute.center = CGPointMake(cellRect.origin.x + attribute.size.width / 2, cellRect.origin.y + attribute.size.height / 2); return attribute; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload