2

Scenario: I have a collection view that is reloaded every 15 seconds. There is no limit to the amount of cells that could be in this collection view, however, only one cell is highlighted at a time. There is only one section, and the collectionview scrolls horizontally. I need to make sure the highlighted cell is always in the center of the phone screen. For example, if the 24th cell is highlighted, it would be a bad user experience to have to scroll all the way until you find it. However, a completely different cell could be highlighted when the collection view gets reloaded in another 15 seconds.

See bottom portion of the image for a better idea of highlighted and unhighlighted cells.

Here's an idea of what I've tried that pertains to the index path of the highlighted cell and making sure it's in the center of the phone screen.

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {

  EZPlayerCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"PlayerCellID" forIndexPath:indexPath];

  NSDictionary *rowData = [[_gameBoardDictionary objectForKey:@"players"] objectAtIndex:indexPath.row];

  if ([[rowData objectForKey:@"possession"] integerValue] == 1) {
     cell.isHighlighted = YES;
  } else {
     cell.isHighlighted = NO;
  }

  if (cell.isHighlighted) {

     self.highlightedCellIndexPath = [self.collectionView indexPathForCell:cell];

  } else {

  }

  return cell;
}

- (void)viewDidLayoutSubviews {

  [self.collectionView scrollToItemAtIndexPath:self.highlightedCellIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];

}

I've tried a number of things, but this should provide a reference for my train of thought. Any help would be appreciated. Thank you so much!

Paul K.
  • 51
  • 1
  • 5
  • Check this answer: http://stackoverflow.com/a/15986085/1091539 – Mutawe Oct 09 '16 at 07:07
  • Yeah, this was one I tried to implement, but I'm not able to correctly get the indexPath to scroll to. **"Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'attempt to scroll to invalid index path".** Any thoughts on how to get the indexPath for the highlighted cell? – Paul K. Oct 10 '16 at 02:30

2 Answers2

0

Please add a observer for the "contentSize" keypath of the collection view.

[self.collectionView addObserver:self forKeyPath:@"contentSize" options:NSKeyValueObservingOptionOld context:NULL];

You can then move the scrolling code inside the observeValueForKeyPath method.

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary  *)changeDict context:(void *)context
{
  [self.collectionView scrollToItemAtIndexPath:self.highlightedCellIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
}
Naveen Ramanathan
  • 2,166
  • 1
  • 19
  • 21
  • I get the following error: **"Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'attempt to scroll to invalid index path"** I'm sure it's because I'm not setting the self.highlightedCellIndexPath correctly in cellForRowAtIndexPath. Any ideas on how to get the accurate indexPath? – Paul K. Oct 10 '16 at 02:05
0

Here's what solved the issue for me. Instead of trying to get the indexPath in cellForItemAtIndexPath, I got the indexPath based on my data and then scrolled to the cell at that indexPath.

NSArray *players = [_gameBoardDictionary objectForKey:@"players"];

self.itemNumber = [players indexOfObjectPassingTest:
                       ^BOOL(NSDictionary *dict, NSUInteger idx, BOOL *stop)
                       {
                           return [[dict objectForKey:@"possession"] isEqual:@1];
                       }
                       ];

[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:self.itemNumber inSection:0] atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
Paul K.
  • 51
  • 1
  • 5