繁体   English   中英

键盘出现时,UICollectionView contentOffset会发生变化

[英]UICollectionView contentOffset changes when keyboard appears

我正在尝试在我的应用中实现PullDown To Search功能。 为了实现这一点,我刚刚修改了位EGOTableViewPullRefresh ,除了一个问题之外它工作得很好。

问题

当用户打开应用程序后,将出现以下屏幕。 最初UICollectionView's contentoffset应为(0,0) 在此输入图像描述

如果用户下拉集合视图,此时将出现以下屏幕, contentoffsetUICollectionView应为(0,-60) 在此输入图像描述

用户可以通过在上面的屏幕中输入文本进行搜索。 如用户点击我的问题是在这个屏幕一旦出现UITextField输入文本contentoffsetUICollectionView变化(0,-60)(0,-110)和UI loosks像波纹管屏。 我不确定为什么会发生这种变化你能指导我解决这个问题吗?

在此输入图像描述

有同样的问题。 覆盖viewWillAppear:viewDidLoad:和文档中告诉的其他方法没有任何效果, TPKeyboardAvoidingScrollView也没有帮助。 在收集视图超过2天后,我遇到了一个非常糟糕的解决方法。 想法是在键盘即将出现时锁定向上滚动,因此您的集合视图不会移动到任何地方,并在键盘结束动画后解锁滚动。 为此,您应该将UICollectionView子类UICollectionView以添加一个锁定滚动,订阅键盘通知并正确设置此标志的标志。

在实施此解决方法之前,我必须警告您,这是一个非常糟糕的主意,在执行此操作之前,您应该尝试其他所有操作。 不过,这有效......

所以这就是你做的:

  1. 在viewController的viewWillAppear中订阅键盘通知:

     - (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中创建键盘处理方法以锁定和解锁滚动:

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

警告! 这里有一个关于keyboardDidShow: dispatch_after的一点说明keyboardDidShow:如果你在键盘显示后立即解锁滚动,将忽略锁定并且收集视图将向上滚动。 将其包装到dispatch_after以在0.3秒后运行此代码并且运行良好。 这可能与运行循环有关, 应该在真实设备上测试,而不是在模拟器中测试。

我在UICollectionView中有一个UITableView并且得到了奇怪的滚动。 受@AnkH的启发我覆盖了我的UICollectionView并将其添加到构造函数中:

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)

在键盘可见时,也覆盖contentOffset并阻止contentOffset的所有修改。 完成。 问题是UITableView已经在其自身上触发了正确的contentOffset设置,但是父UICollectionView添加了自己的contentOffset,导致了灾难性的行为。 首先它滚动太远,然后太远了。 现在它完美无瑕!

处理这个也不是一个漂亮的解决方案

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

最简单的替代方法是使用UIViewController并添加自己的UICollectionView。 禁用键盘所有不良行为所需的疯狂黑客数量只是疯了。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM