title: How to determine indexPath of currently visible UICollectionView cell
body: <p>I want to display some cell-specific text, but I can’t extricate the visible cell from the collection view.</p>
  
  <p>Most helpful ones were these: </p>
  
  <p><a href="https://stackoverflow.com/questions/13875428/how-to-access-from-uicollectionviewcell-the-indexpath-of-the-cell-in-uicollectio">how to access from UICollectionViewCell the indexPath of the Cell in UICollectionView</a></p>
  
  <p><a href="https://stackoverflow.com/questions/18465489/detecting-when-an-ios-uicollectioncell-is-going-off-screen">detecting when an iOS UICollectionCell is going off screen</a></p>
  
  <p>A lower collection view (self addSubview) contains possible items.  An upper one (self addSubview) contains selections from the lower.  The user presses a button (self addSubview again), the lower view scrolls off to oblivion and the upper one expands such that one cell fills the screen.  All the array-building and displaying works fine.  No *.nibs.  </p>
  
  <p>What doesn’t work is figuring out which cell the app is presenting to the user.</p>
  
  <p>TRY #1: First I tried populating the UILabel in parallel with normal ops. Press the button and cellForItemAtIndexPath:</p>
  
  <pre><code>if (cv.tag == UPPER_CV_TAG) {
      UICollectionViewLayoutAttributes *itemAttributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath];
      NSIndexPath *tempIndexPath;
  tempIndexPath = itemAttributes.indexPath;
  NSLog(@"cellForItem indexPath %@",indexPath);
  NSLog(@"layout indexPath %@",tempIndexPath);
  }
  </code></pre>
  
  <p>responds as you’d expect:</p>
  
  <pre><code>cellForItem indexPath &lt;blah blah&gt; 2 indexes [0, 0]
  layout indexPath &lt; &gt; 2 indexes [0, 0]
  
  cellForItem indexPath &lt; &gt; 2 indexes [0, 1]
  layout indexPath &lt; &gt; 2 indexes [0, 1]
  
  cellForItem indexPath &lt; &gt; 2 indexes [0, 2]
  layout indexPath &lt; &gt; 2 indexes [0, 2]
  </code></pre>
  
  <p>When the gyrations conclude, Cell 0 correctly occupies center stage.  Unfortunately, so does the description for cell 2.  Scroll left / right, cells change accordingly, the corresponding text does not.  It remains constant: that which maps to cell 2.</p>
  
  <p>Obviously I’m passing the wrong index to the description array.  </p>
  
  <p>TRY #2: OK, fine.  I’ll interrogate a point I know the currently visible cell occupies and reason backward from that.</p>
  
  <pre><code>CGPoint p = CGPointMake(512, 456);
  NSIndexPath *theCellsIndexPath = [self.upper_collectionView indexPathForItemAtPoint:p];
  NSLog(@"theCellsIndexPath=%d",theCellsIndexPath.item);
  </code></pre>
  
  <p>No cigar:</p>
  
  <pre><code>cellForItem indexPath &lt; &gt; 2 indexes [0, 0]
  theCellsIndexPath=0
  
  cellForItem indexPath &lt; &gt; 2 indexes [0, 1]
  theCellsIndexPath=0
  
  cellForItem indexPath &lt; &gt; 2 indexes [0, 2]
  theCellsIndexPath=0
  </code></pre>
  
  <p>No change from “0” when I change 512,456 to other likely points. No change from “0” when I use layoutAttributes to determine where in the view the cell lies, just in case.  Nope, that cell is a really, really big target.  I’m not missing it.</p>
  
  <p>TRY #3: Maybe I’m working too hard.  I’ll trap the goings-on inside</p>
  
  <pre><code>- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath  {
  }
  </code></pre>
  
  <p>and roll with that.</p>
  
  <p>Nope.  It never gets called.</p>
  
  <p>TRY #4: Since I don’t know the indexPath of the single cell on the screen (but the collectionView does) I suppose I could iterate through all the cells with didEndDisplayingCell until I hit “Bingo!”  That’s crude and indicative of programmer error.</p>
  
  <p>I’m glad the collectionView logic buffers three cells.  Probably improves user experience or something.  But where it ends up – on 0 – is not where my array index last knew it was – at 2.  </p>
  
  <p>What part of the docs didn’t I read?</p>