Had the same issue. Overriding viewWillAppear:
, viewDidLoad:
and other methods as told in documentation had no effect, TPKeyboardAvoidingScrollView
didn't help either. After struggling with collection view for over 2 days I've come to a really bad workaround. The idea is to lock scrolling up when keyboard is about to appear, so your collection view will not move anywhere, and unlock scroll after keyboard ends animation. To do so you should subclass UICollectionView
to add a flag that locks scroll, subscribe to keyboard notifications and set this flag properly.
Before you implement this workaround, I must warn you that this is a VERY bad idea, and you should try everything else before doing that. Still, this works...
So here is what you do:
In viewWillAppear of your viewController subscribe for keyboard
notifications:
- (void)viewWillAppear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardWillShow:)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardDidShow:)
name:UIKeyboardDidShowNotification
object:nil];
// you custom code here
}
You will handle notifications later
Don't forget to unsubscribe from notifications:
- (void)viewWillDisappear:(BOOL)animated
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
// your custom code
}
Subclass UICollectionView and add flag:
@property (nonatomic, getter=isLocked) BOOL locked;
Override setContentOffset: in your collection view:
- (void)setContentOffset:(CGPoint)contentOffset
{
if (contentOffset.y < self.contentOffset.y && self.isLocked) // user scrolls up
contentOffset.y = self.contentOffset.y; // ignore new Y coordinate, so collection view will not scroll up
[super setContentOffset:contentOffset];
}
In your viewController create methods for keyboard handling to lock and unlock scroll:
- (void)keyboardWillShow:(NSNotification *)aNotification
{
[(LockableCollectionView *)self.collectionView setLocked:YES];
}
- (void)keyboardDidShow:(NSNotification *)aNotification
{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[(LockableCollectionView *)self.collectionView setLocked:NO];
});
}
Warning! Here is a little clarification about dispatch_after
in keyboardDidShow:
If you unlock scroll right after keyboard did show, locking will be ignored and collection view will scroll up. Wrap it into dispatch_after
to run this code after 0.3 seconds and it works well. This is probably related with run loops and should be tested on real devices, not in simulator.
TPKeyboardAvoidingScrollView
class from cocoacontrols.com ? – Nudicaul