--- title: UICollectionView Challenges layout: docs permalink: /docs/uicollectionview-challenges.html --- `UICollectionView` is one of the most commonly used classes and many challenges with iOS development are related to its architecture. ## How `UICollectionView` Works There are two important methods that `UICollectionView` requires.

Cell Measurement

For each item in the data source, the collection must know its size to understand which items should be visible at a given momement. This is provided by:
SwiftObjective-C
- (CGSize)collectionView:(UICollectionView *)collectionView 
                  layout:(UICollectionViewLayout *)collectionViewLayout 
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
Although not formally named by Apple, we refer to this process as "measuring". Implementing this method is always difficult, because the view that implements the cell layout is never available at the time of this method call. This means that logic must be duplicated between the implementation of this method and the `-layoutSubviews` implementation of the cell subclass. This presents a tremendous maintainence burden, as the implementations must always match their behavior for any combination of content displayed. Additionally, once measurement is complete, there's no easy way to cache that information to use it during the layout process. As a result, expensive text measurements must be repeated.

Cell Allocation

Once an item reaches the screen, a view representing it is requested:
SwiftObjective-C
- (UICollectionViewCell *)cellForItemAtIndexPath:(NSIndexPath *)indexPath;
In order to provide a cell, all subviews must be configured with the data that they are intended to display. Immediately afterwards, the layout of the cell is calculated, and finally the display (rendering) of the individual elements (text, images) contained within.
For those who are curious, this extremely detailed diagram shows the full process of UICollectionView communicating with its data source and delegate to display itself.

Limitations in `UICollectionView`'s Architecture

There are several issues with the architecture outlined above: Lots of main thread work, which may degrade the user's experience, including Duplicated layout logic You must have duplicate copies of your cell sizing logic for the cell measurement and cell layout stages. For example, if you want to add a price tag to your cell, both -sizeForItemAtIndexPath and the cell's own -layoutSubviews must be aware of how to size the tag. No automatic content loading There is no easy, universal way to handle loading content such as: ## How `ASCollectionNode` works

Unified Cell Measurement & Allocation

Texture takes both of the important collection methods explained above:
SwiftObjective-C
- (UICollectionViewCell *)cellForItemAtIndexPath:(NSIndexPath *)indexPath;

- (CGSize)collectionView:(UICollectionView *)collectionView 
                  layout:(UICollectionViewLayout *)collectionViewLayout 
  sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
and replaces them with a single method*:
SwiftObjective-C
- (ASCellNode *)collectionNode:(ASCollectionNode *)collectionNode nodeForItemAtIndexPath:(NSIndexPath *)indexPath;
or with the asynchronous versions
SwiftObjective-C
- (ASCellNodeBlock)collectionNode:(ASCollectionNode *)collectionNode nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath;
*Note that there is an optional method to provide a constrained size for the cell, but it is not needed by most apps. ASCellNode, is Texture's universal cell class. They are light-weight enough to be created an an earlier time in the program (concurrently in the background) and they understand how to calculate their own size. `ASCellNode` automatically caches its measurement so that it can be quickly applied during the layout pass.
As a comparison to the diagram above, this detailed diagram shows the full process of an ASCollectionView communicating with its data source and delegate to display itself.. Note that ASCollectionView is ASCollectionNode's underlying UICollectionView subclass.

Benefits of Texture's Architecture

Elimination of all of the types of main thread work described above (cell allocation, measurement, layout, display)! In addition, all of this work is preformed concurrently on multiple threads. Because `ASCollectionNode` is aware of the position of all of its nodes, it can automatically determine when content loading is needed. The Batch Fetching API handles loading of data pages (like JSON) and Intelligent Preloading automatically manages the loading of images and text. Additionally, convenient callbacks allow implementing accurate visibility logging and secondary data model requests. Lastly, almost all of the concepts we've discussed here apply to `UITableView` / `ASTableNode` and `UIPageViewController` / `ASPagerNode`. ## iOS 10 Cell Pre-fetching Inspired by Texture, iOS 10 introduced a cell pre-fetching. This API increases the number of cells that the collection tracks at any given time, which helps, but isn't anywhere as performance centric as being aware of all cells in the data source. Additionally, iOS9 still constitutes a substantial precentage of most app's userbase and will not reduce in number anywhere close to as quickly as the sunset trajectory of iOS 7 and iOS 8 devices. Whereas iOS 9 is the last supported version for about a half-dozen devices, there were zero devices that were deprecated on iOS 8 and only one deivce deprecated on iOS 7. Unfortunately, these iOS 9 devices are the ones in which performance is most key!