I have a method that I use to scroll to the bottom of my collectionView
- (void) scrollToBottom {
if (_messagesArray.count > 0) {
static NSInteger section = 0;
NSInteger item = [self collectionView:_myCollectionView numberOfItemsInSection:section] - 1;
if (item < 0) item = 0;
NSIndexPath *lastIndexPath = [NSIndexPath indexPathForItem:item inSection:section];
[_myCollectionView scrollToItemAtIndexPath:lastIndexPath atScrollPosition:UICollectionViewScrollPositionBottom animated:YES];
}
}
And it works perfectly! I have never had a problem at any point, it works 100% consistent . . . with a modal view presentation. If however, I push the viewController onto a navigation controller, it doesn't work. Rather, it only works if there's over 15 cells. Once I reach at least 15 cells, it again begins behaving perfectly. Prior to 15 cells, it either doesn't scroll at all, or scrolls a little bit.
I realize this is a long shot, but I'm scratching my head on this one and I thought maybe somebody might know what the heck is happening.
Troubleshoots:
Have you logged to make sure it's running? YES
Have you logged index path to make sure its trying to scroll to the correct index path? YES
There is a automaticallyAdjustsScrollViewInsets
property in UIViewController
, and as it's inherited, in UINavigationController
. Set it to NO
in self.navigationController
and it won't adjust your insets, as documented here
I found the problem.
The NavigationController was automatically adjusting my top content inset for some reason. I was able to prevent this behavior by adding this:
- (void) scrollToBottom {
if (_isNavigationControllerVersion) {
_myCollectionView.contentInset = UIEdgeInsetsZero;
}
if (_messagesArray.count > 0) {
static NSInteger section = 0;
NSInteger item = [self collectionView:_myCollectionView numberOfItemsInSection:section] - 1;
if (item < 0) item = 0;
NSIndexPath *lastIndexPath = [NSIndexPath indexPathForItem:item inSection:section];
[_myCollectionView scrollToItemAtIndexPath:lastIndexPath atScrollPosition:UICollectionViewScrollPositionBottom animated:YES];
}
}
So, since your .gif demonstrates that the problem is happening when the keyboard is open, I can only assume that the bottom scroll is within the content inset of the collection view, even if it is behind the keyboard.
Be sure you're resetting the content inset when the keyboard appears/disappears. I will edit in some example code.
First, you need to register for the notifications:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWasShown:)
name:UIKeyboardDidShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillHide:)
name:UIKeyboardWillHideNotification
object:nil];
This should go in viewDidLoad
. Don't forget to removeObserver
in dealloc
.
Now set the content insets in these methods:
- (void)keyboardWasShown:(NSNotification *)aNotification {
CGSize kbSize = [[[aNotification userInfo] objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
UIEdgeInsets insets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0);
yourCollectionView.contentInset = Insets;
yourCollectionView.scrollIndicatorInsets = Insets;
}
- (void) keyboardWillHide:(NSNotification *)aNotification {
UIEdgeInsets insets = UIEdgeInsetsZero;
yourCollectionView.contentInset = contentInsets;
yourCollectionView.scrollIndicatorInsets = contentInsets;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With