简体   繁体   中英

How to make sure changing collectionview cells appear at the center of the phone screen?

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!

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];
}

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];

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM