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

时间:2014-06-17 06:06:49

标签: ios objective-c uiscrollview uicollectionview contentoffset

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

问题

当用户打开应用程序后,将出现以下屏幕。最初UICollectionView's contentoffset应为(0,0) enter image description here

如果用户下拉集合视图,此时将显示以下屏幕contentoffset UICollectionView(0,-60) enter image description here

用户可以在上面的屏幕中输入文字进行搜索。一旦用户点击UITextField以输入contentoffset更改UICollectionView (0,-60) (0,-110)的文字{{1}}和屏幕下方的用户体验,我的问题就出现在此屏幕上。我不确定为什么会发生这种变化你能引导我解决这个问题吗?

enter image description here

5 个答案:

答案 0 :(得分:1)

有同样的问题。覆盖viewWillAppear:viewDidLoad:和文档中说明的其他方法无效,TPKeyboardAvoidingScrollView也无济于事。在收集视图超过2天后,我遇到了一个非常糟糕的解决方法。想法是在键盘即将出现时锁定向上滚动,因此您的集合视图不会移动到任何地方,并在键盘结束动画后解锁滚动。为此,您应该将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
    }
    
  2. 您稍后会处理通知

    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];
          });
      }
      
    5. 警告!以下是对dispatch_afterkeyboardDidShow:的一点说明 如果在键盘确实显示后立即解锁滚动,则会忽略锁定并且向上滚动收集视图。将其包装到dispatch_after以在0.3秒后运行此代码并且运行良好。这可能与运行循环有关,应该在真实设备上测试,而不是在模拟器中测试。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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

答案 4 :(得分:0)

我在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,导致了灾难性的行为。首先它滚动太远,然后太远了。现在它完美无缺!