RxSwiftCommunity / RxKeyboard

Reactive Keyboard in iOS
MIT License
1.6k stars 175 forks source link

Bug on iPhone X #84

Open AlexisQapa opened 5 years ago

AlexisQapa commented 5 years ago

Hello,

On iPhone X, Xr, Xs in the example when you tap the search bar and the keyboard appear there is a gap between the bar and the keyboard. The reason is because it's constrained to the safe area in MessageListViewController (96) : if #available(iOS 11.0, *) { make.bottom.equalTo(self.view.safeAreaLayoutGuide.snp.bottom).offset(-keyboardVisibleHeight) } else { make.bottom.equalTo(self.bottomLayoutGuide.snp.top).offset(-keyboardVisibleHeight) }

While this is intended behaviour when there is no keyboard this doesn't work when it open. I'm gonna try to fix it but if someone as a nice way to do it it would be great to have it in the example.

cfr commented 5 years ago

Hey, not sure it is related: I'm also experience this bug on X with google keyboard. It is reporting wrong visibleHeight on new devices or OS, though It seems RxKeyboard.instance.frame is OK.

pauloec commented 5 years ago

Having the same issue. Not sure if someone tested with iPhone X models. safeAreaInsets are not taken into account and when using visibleHeight it is 0 because it hasn't been drawn yet.

yojkim commented 4 years ago

Same issue on me. Third-party keyboards return wrong visibleHeight value 🤔

shingo-nakanishi commented 4 years ago

Same issue on my project without SnapKit.

I solved it as follows.

@IBOutlet weak var bottomConstraint: NSLayoutConstraint!

and

RxKeyboard.instance.visibleHeight.drive(onNext: { [weak self] visibleHeight in
    guard let weakSelf = self else {
        return
    }

    if #available(iOS 11.0, *) {
        if visibleHeight == 0 {
            weakSelf.bottomConstraint.constant = 0
        } else {
            let height = visibleHeight - weakSelf.view.safeAreaInsets.bottom
            weakSelf.bottomConstraint.constant = -1 * height
        }
    } else {
        weakSelf.bottomConstraint.constant = -1 * visibleHeight
    }

    weakSelf.view.setNeedsLayout()
    weakSelf.view.layoutIfNeeded()
}).disposed(by: disposeBag)

Reference https://stackoverflow.com/questions/46420488/iphonex-and-iphone-8-keyboard-height-are-different

jinuman commented 4 years ago

Same issue on me as well.

@IBOutlet weak var bottomConstraint: NSLayoutConstraint!

I am wondering where this constraint is hanging. @shingo-nakanishi Could you answer me?

James-Geng commented 2 years ago

I solved as follows.

RxKeyboard.instance.visibleHeight
      .drive(onNext: { [weak self] keyboardVisibleHeight in
        guard let `self` = self, self.didSetupViewConstraints else { return }
        self.messageInputBar.snp.remakeConstraints { make in
            make.left.right.equalTo(0)
          if #available(iOS 11.0, *) {
              if keyboardVisibleHeight == 0 {
                  make.bottom.equalTo(self.view.safeAreaLayoutGuide.snp.bottom).offset(-keyboardVisibleHeight)
              }
              else {
                  make.bottom.equalTo(self.view.snp.bottom).offset(-keyboardVisibleHeight)
              }

          } else {
            make.bottom.equalTo(self.bottomLayoutGuide.snp.top).offset(-keyboardVisibleHeight)
          }
        }
        self.view.setNeedsLayout()
        UIView.animate(withDuration: 0) {
          self.collectionView.contentInset.bottom = keyboardVisibleHeight + self.messageInputBar.height
          self.collectionView.scrollIndicatorInsets.bottom = self.collectionView.contentInset.bottom
          self.view.layoutIfNeeded()
        }
      })
      .disposed(by: self.disposeBag)