0

Currently, I have a UICollectionView, which multiple rows of UITextField.

When the bottom UITextField, keyboard will block its visibility.

To make UICollectionView still scrollable to bottom, many techniques have been intoriduced


Most solution ideas are

  1. Calculate the high of keyboard.
  2. Adjust the contentInset and scrollIndicatorInsets of UICollectionView

However, such solution doesn't work very well, if my screen is consists of a UICollectionView and a bottom UIView.


When keyboard is hidden

--------------------
|                  |
|                  |
|                  |
|                  |
| UICollectionView |
|                  |
|                  |
|                  |
|                  |
--------------------
|                  |
|  Custom UIView   |
|                  |
-------------------- 

When keyboard is shown (My expectation)

--------------------
|                  |
|                  |
| UICollectionView |
|                  |
|                  |
--------------------
|                  |
|  Custom UIView   |
|                  |
-------------------- 
|                  |
|                  |
|  Keyboard        |
|                  |
--------------------

However, current provided solution, is only able to "push up" UIScrollView/ UICollectionView.

I tend to "push up" entire main UIView. Unfortunately, UIView doesn't have contentInset for me to act upon, based on keyboard height.

This is my current outcome using https://github.com/hackiftekhar/IQKeyboardManager. The outcome is the same, if I apply solution from https://stackoverflow.com/a/32353069/72437


When keyboard is hidden

enter image description here


When keyboard is shown. Only UICollectionView is being pushed up. The bottom UIView will be "covered"

enter image description here


Any idea how I can "push up" entire app screen, instead of just UICollectionView/ UIScrollView?

Cheok Yan Cheng
  • 49,649
  • 117
  • 410
  • 768
  • Yes, it is possible https://stackoverflow.com/questions/26070242/move-view-with-keyboard-using-swift – Roman Ryzhiy Sep 11 '20 at 08:44
  • You don't even need to handle the inset, just calculate the keyboard height, then change the constant of the bottomMostView-to-superView constraint, then whole view will push up. – Tj3n Sep 11 '20 at 08:50
  • I would consider a [solution that adjusts the safeAreaLayoutGuide](https://stackoverflow.com/questions/45399178/extend-ios-11-safe-area-to-include-the-keyboard) so that it works across all devices. – Wez Sep 11 '20 at 15:56
  • 1
    @Wez Thanks for the pointer. I will look at them as well. In fact, I think this should be the responsible of OS, to ensure keyboard doesn't cover up the app. It shouldn't require all the ugly manual handling from app developers. 1 trillion dollar company should know this better. – Cheok Yan Cheng Sep 11 '20 at 16:00

1 Answers1

0

One of the most popular answer (https://stackoverflow.com/a/31124676/72437) is adjusting the Y of the view.

However, that is a wrong solution, if one of the UI component inside the view is UICollectionView. You will not able to scroll till the start of the list, after you adjust Y of the view.

The correct solution should be adjusting the height of the view.

private var originalSize: CGSize?

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    NotificationCenter.default.removeObserver(self)
}

@objc func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        if self.originalSize == nil {
            let originalSize = self.view.frame.size
            self.originalSize = originalSize
            self.view.frame.size = CGSize(
                width: originalSize.width,
                height: originalSize.height - keyboardSize.height
            )
        }
    }
}

@objc func keyboardWillHide(notification: NSNotification) {
    if let originalSize = self.originalSize {
        self.view.frame.size = originalSize
        self.originalSize = nil
    }
}
Cheok Yan Cheng
  • 49,649
  • 117
  • 410
  • 768