UICollectionView contentOffset changes with custom layout

I started to find this issue appearing on iOS 11 where I had a scrollview within a scroll view. Took me almost a day to figure it out.

Try setting the content inset adjustment behaviour:

if #available(iOS 11.0, *) {
    scrollView.contentInsetAdjustmentBehavior = .never
}

This fixed my collectionview adjusting it's content inset down a small amount as the collectionview frame would move past the safe area of the enclosing scrollview.


I found the reason why this happens. Check the accepted answer from this question: Status bar and navigation bar appear over my view's bounds in iOS 7

Indeed, we could just set edgesForExtendedLayout or automaticallyAdjustsScrollViewInsets properties of UIViewController in IB (if you use Storyboard) of in viewDidLoad and it will fix our issue.

Just don't forget check for this property is available, because in iOS6 or prior it will cause crash:

if ([self respondsToSelector:@selector(setAutomaticallyAdjustsScrollViewInsets:)]) {
    self.automaticallyAdjustsScrollViewInsets = NO;
}

Regards!


The only solution I could come up with that had barely-acceptable behavior:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (self.collectionView.contentOffset.y < 0) {
        self.collectionView.contentOffset = CGPointMake(self.collectionView.contentOffset.x, 0.0);
    }
}

As well as setting the height of the content to fmax(self.collectionView.frame.size.height + 20, [self stackedSectionHeight]) in collectionViewContentSize

This removes the space above the section header, but it removes the "bounce" from the top. A pretty sub-optimal solution, but fairly acceptable.

I'll accept a better answer if anyone has one, or if I find one I'll update this answer.