Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adjust collectionView.scrollToItem to consider inset?

I'm sometimes scroll to the left of a cell like this:

collectionView.scrollToItem(
    at: IndexPath(row: 5, section: 0),
    at: .left, // TODO: Left ignores inset
    animated: true
)

This is how it starts out before scrollToItem implemented:

enter image description here

However, when I try to use scroll to item, it sticks the cell to the edge instead of considering the inset:

enter image description here

Is there an easy way to fix collectionView.scrollToItem to accommodate the insets?

like image 247
TruMan1 Avatar asked Jun 26 '18 04:06

TruMan1


4 Answers

You can use the regular method collectionView.scrollToItem if you set your inset in collectionView.contentInset instead of layout.sectionInset.

like image 76
Paweł Zgoda-Ferchmin Avatar answered Oct 17 '22 08:10

Paweł Zgoda-Ferchmin


Objective-C

   /**
     Assumptions:
     1. Your collection view scrolls horizontally
     2. You are using UICollectionViewFlowLayout to layout you collection view

     @param indexPath IndexPath to scroll to
     @param animated Toggle animations
     */
    - (void)scrollToIndexPathPreservingLeftInset:(NSIndexPath *)indexPath animated:(BOOL)animated {
        UICollectionViewFlowLayout *layout = (UICollectionViewFlowLayout *)collectionView.collectionViewLayout;
        CGFloat sectionLeftInset = layout.sectionInset.left;
        UICollectionViewLayoutAttributes *attri = [layout layoutAttributesForItemAtIndexPath:indexPath];
        [collectionView setContentOffset:CGPointMake(attri.frame.origin.x - sectionLeftInset, 0) animated:animated];
    }

Swift (not verified syntactically)

func scroll(toIndexPathPreservingLeftInset indexPath: IndexPath, animated: Bool) {
    let layout = collectionView.collectionViewLayout as! UICollectionViewFlowLayout
    let sectionLeftInset = layout.sectionInset.left
    var attri = layout.layoutAttributesForItem(at: aPath)
    collectionView.setContentOffset(CGPoint(x: (attri?.frame.origin.x - sectionLeftInset), y: 0), animated: animated)
}

Sample gif

like image 23
BangOperator Avatar answered Oct 17 '22 07:10

BangOperator


Set conentInset value to your collectionView like this:

myCollectionView.contentInset = UIEdgeInsets(top: 0, left: 10, bottom: 0, right: 10)

and then add this line:

 if #available(iOS 11, *) {
            self.myCollectionView.contentInsetAdjustmentBehavior =     .never
        }

then scrolltoItem works by respecting the insets of collectionView.

like image 28
Frankenxtein Avatar answered Oct 17 '22 07:10

Frankenxtein


Since each cell's frame takes into account its section inset, you may as well use scrollRectToVisible(_:animated:).

let cell = collectionView.cellForItem(at: indexPath)!
collectionView.scrollRectToVisible(cell.frame, animated: true)

And since it is a frame we're working on, you can fine tune some desired offset to that frame.

like image 32
nyrd Avatar answered Oct 17 '22 09:10

nyrd