出现键盘时,UICollectionView contentOffset会更改

我正试图在我的应用程序中实现PullDown To Searchfunction。 为了实现这个,我只是修改了一下EGOTableViewPullRefresh ,除了一个问题外,它工作的很好。

问题

当用户打开应用程序时,将出现以下屏幕。 最初UICollectionView's contentoffset应该是(0,0) 在这里输入图像说明

如果用户拉下集合视图,此时出现下面的屏幕, contentoffsetUICollectionView应该是(0,-60) 在这里输入图像说明

用户可以在上面的屏幕中input文字进行search。 当用户点击UITextFieldinputcontentoffset的文本contentoffset (0,-60)(0,-110)和UI loosks(如下图屏幕(0,-110) ,我的问题就发生在这个屏幕上。 我不知道为什么会发生这种变化,请你指导我解决这个问题?

在这里输入图像说明

有同样的问题。 重写viewWillAppear:viewDidLoad:和文档中告诉的其他方法没有效果, TPKeyboardAvoidingScrollView也没有帮助。 经过两天的收集视图苦苦挣扎,我已经到了一个非常糟糕的解决方法。 这个想法是当键盘即将出现时locking滚动,所以你的collections视图将不会移动到任何地方,并且在键盘结束animation之后解锁滚动。 为此,您应该子类UICollectionView添加一个标志locking滚动,订阅键盘通知并正确设置此标志。

在实施此解决方法之前,我必须警告您,这是一个非常糟糕的主意,您应该在做这件事之前尝试其他一切。 不过,这工作…

所以,这就是你所做的:

  1. 在viewWill你的viewController的订阅键盘通知:

     - (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 } 

稍后您将处理通知

  1. 不要忘记取消订阅通知:

     - (void)viewWillDisappear:(BOOL)animated { [[NSNotificationCenter defaultCenter] removeObserver:self]; // your custom code } 
  2. 子类UICollectionView并添加标志:

     @property (nonatomic, getter=isLocked) BOOL locked; 
  3. 覆盖您的集合视图中的setContentOffset:

     - (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]; } 
  4. 在您的viewController创build键盘处理方法来locking和解锁滚动:

     - (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]; }); } 

警告! 下面是关于dispatch_afterkeyboardDidShow:的一些说明keyboardDidShow:如果在键盘显示后解锁滚动,locking将被忽略,集合视图将向上滚动。 将其包装到dispatch_after ,在0.3秒后运行此代码,并且工作正常。 这可能与运行循环有关, 应该在真实设备上进行testing,而不是在模拟器上进行testing。

也不是一个美丽的解决办法来处理这个

 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 } } 

最简单的select是使用UIViewController并添加自己的UICollectionView。 为了禁用所有不需要的键盘操作,疯狂的黑客数量是疯狂的。

问题解决! 通过UIViewController更改我的UICollectionViewController并使我的UICollectionView成为ViewController.view的子视图。