I am trying to implement PullDown To Search
feature in my app. To implement this i just modified bit EGOTableViewPullRefresh
it is working good except an issue.
Issue
When user opens the application following screen shall appear. initially the UICollectionView's
contentoffset
shall be (0,0)
If user pulls down the collection view the following screen shall appear at this point the contentoffset
of UICollectionView
shall be (0,-60)
User can search by entering their text in the above screen. My issue is occurring in this screen as soon as user taps the UITextField
to enter text contentoffset
of UICollectionView
changes (0,-60)
to (0,-110)
and UI loosks like bellow screen. I am not sure why this change occurs can you please guide me to resolve this?
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.
I had an UITableView inside an UICollectionView and got weird scrolling. Inspired by @AnkH I override my UICollectionView and added this into the constructor:
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow),
name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidHide),
name: NSNotification.Name.UIKeyboardDidHide, object: nil)
Override contentOffset too and blocked all modifications of contentOffset while the keyboard was visible. Done. The problem is that UITableView already triggers the correct contentOffset setting on itself, but then the parent UICollectionView adds its own contentOffset, resulting in disastrous behaviour. First it was scrolling too far up, then too far down. Now it works flawlessly!
also not a beautiful solution to handle this
NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: UIKeyboardWillShowNotification, object: nil)
func keyboardWillShow() {
let offset = self.collectionView!.contentOffset;
self.collectionView!.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right:0 )
self.collectionView!.contentOffset = offset
let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
let offset = self.collectionView!.contentOffset;
self.collectionView!.contentInset = UIEdgeInsets(top: 60, left: 0, bottom: 0, right:0 )
self.collectionView!.contentOffset = offset
}
}
The easiest alternative is to use a UIViewController and add your own UICollectionView. The amount of crazy hacks needed to disable all the undesired behavior of the keyboard is just insane.
problem solve! changing my UICollectionViewController by a UIViewController and make my UICollectionView a subView of my ViewController.view.
来源:https://stackoverflow.com/questions/24256752/uicollectionview-contentoffset-changes-when-keyboard-appears