I have a UICollectionView
and it has quite a lot of UICollectionViewCells
on it. I want to scroll the cell to the centre of the UICollectionView
when it is tapped. My concern is that even if I tap the last or the top cell it should move to the centre of the collection view.
I have tried setting the contentInsets
and offsets but they don't seem to work. I think I will have to change the content size on selection and change it back to original when the scrolling begins.
Setting contentInsets should give some extra space around first and last cells:
CGFloat collectionViewHeight = CGRectGetHeight(collectionView.bounds);
[collectionView
setContentInset:
UIEdgeInsetsMake(collectionViewHeight/2, 0, collectionViewHeight/2, 0) ];
// nb, those are top-left-bottom-right
After you should call:
[collectionView scrollToItemAtIndexPath:selectedItemPath
atScrollPosition:UICollectionViewScrollPositionCenteredVertically
animated:YES];
It's important to pass correct scroll position: UICollectionViewScrollPositionCenteredVertically
This should center tapped item properly.
EDIT
It's really strange, but after setting UIEdgeInsets to collection view method scrollToItemAtIndexPath does not works properly, so i make some modification:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
CGFloat collectionViewHeight = CGRectGetHeight(self.collectionView.frame);
[collectionView setContentInset:UIEdgeInsetsMake(collectionViewHeight / 2, 0, collectionViewHeight / 2, 0)];
UICollectionViewCell *cell = [collectionView cellForItemAtIndexPath:indexPath];
CGPoint offset = CGPointMake(0, cell.center.y - collectionViewHeight / 2);
[collectionView setContentOffset:offset animated:YES];
}
it works fine for me.
It seems that this bug is caused by a bad interaction between the scroll view's contentInset
and UICollectionViewFlowLayout
. In my testing, setting layout.sectionInset
rather than collectionView.contentInset
eliminated the problem.
Based on the accepted answer above, I would eliminate the workaround, and change:
[collectionView setContentInset:UIEdgeInsetsMake(collectionViewHeight / 2, 0, collectionViewHeight / 2, 0)];
to
[layout setSectionInset:UIEdgeInsetsMake(collectionViewHeight / 2, 0, collectionViewHeight / 2, 0)];
Swift 3 solution for scrolling and centering screen to make the tapped item visible:
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
collectionView.scrollToItem(at: indexPath, at: .centeredVertically, animated: true)
}
This doesn't add inset above or under the collectionView
!
You can use scrollToItemAtIndexPath
method to put selected(tapped) cell to center position in UICollectionView
[collectionView scrollToItemAtIndexPath:indexPath
atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally
animated:true];
You can use UICollectionViewScrollPositionCenteredVertically
for vertical centered position