title: UICollectionView Scroll Performance Horrible
body: <p>I have around 14 items in my collectionView and the scrolling is not smooth at all. I am using auto layout (my constraints don't log errors), and I am using the cornerRadius property (it's a messaging app).</p>
  
  <p>I've tried analyzing it using the Time Profiler instrument, and this was what I see when I scroll:</p>
  
  <p><a href="https://i.stack.imgur.com/Bzm1g.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Bzm1g.png" alt="enter image description here"></a></p>
  
  <p>Unfortunately "Reveal in Xcode" is grayed out, so I can't see exactly what line is taking forever. I am calculating the size of each item though. I'm wondering what the huge 9377 ms delay could be? I'm not using ordered sets if I recall correctly.</p>
  
  <p>Here's my <code>cellForItemAtIndexpath</code> method:</p>
  
  <pre><code>- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
  
      //Define Message
      Message *message = (Message *)[self.messages objectAtIndex:indexPath.item];
  
      //Check Message Type
      switch (message.type) {
          case MessageTypeText: {
  
              //Initialize Cell
              TextMessageItem *cell = (TextMessageItem *)[collectionView dequeueReusableCellWithReuseIdentifier:kTextMessageItemIdentifier forIndexPath:indexPath];
  
              //Return Cell
              return cell;
  
              break;
          }
      }
  
      return nil;
  }
  </code></pre>
  
  <p>Here's how i'm calculating the height:</p>
  
  <pre><code>- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
  
      //Retrieve the right message
      Message *message = (Message *)[self.messages objectAtIndex:indexPath.row];
  
      //Check Message Type
      switch (message.type) {
          case MessageTypeText: {
  
              //Create a temporary cell to get the correct size
              TextMessageItem *tempCell = [[TextMessageItem alloc] init];
  
              //Configure the cell
              [self collectionView:collectionView configureTextCell:tempCell atIndexPath:indexPath];
  
              CGSize s = [tempCell systemLayoutSizeFittingSize:UILayoutFittingCompressedSize withHorizontalFittingPriority:UILayoutPriorityDefaultHigh verticalFittingPriority:UILayoutPriorityDefaultLow];
  
              //Return Content Size
              return CGSizeMake(self.collectionView.bounds.size.width, s.height);
  
              break;
          }
      }
  
      //Return
      return CGSizeMake(0, 0);
  }
  </code></pre>
  
  <p>My <code>WillDisplayCell</code> Method: </p>
  
  <pre><code>- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath {
  
      //Retrieve message from our array of messages
      Message *message = (Message *)[self.messages objectAtIndex:indexPath.row];
  
      //Check Message Type
      switch (message.type) {
          case MessageTypeText: {
  
              //Cast Cell
              TextMessageItem *textItem = (TextMessageItem *)cell;
              [self collectionView:collectionView configureTextCell:textItem atIndexPath:indexPath];
  
              break;
          }
      }
  }
  </code></pre>
  
  <p>And lastly, this is my custom <code>configureTextCell</code> method:</p>
  
  <pre><code>- (void)collectionView:(UICollectionView *)collectionView configureTextCell:(TextMessageItem *)item atIndexPath:(NSIndexPath *)indexPath {
  
      //Retrieve Message
      Message *message = (Message *)[self.messages objectAtIndex:indexPath.item];
  
      //Display Timestamp if Needed
      [self displayTimestampForItemIfNeeded:item atIndex:indexPath.item];
  
      //Update Top Message Padding Based On Who Sent The Previous Message
      [self updateDistanceFromPreviousMessageForItem:item atIndex:indexPath.item];
  
      //Display Delivery Status if Needed (e.g. Delivered)
      [self displayDeliveryStatusForItemIfNeeded:item atIndex:indexPath.item];
  
      //Set Message
      [item setMessage:message];
  }
  </code></pre>