5

I'm using IQKeyboardManager to keep the text fields to go up after typing with the keyboard.

I don't want to scroll to a specific view even when clicked on the text field. Below is the screenshot of the design. I want the 'header' to remain on top.

inspector layout for the view

From their documentation, there is a way to keep the navigation bar remain on top.

Tamás Sengel
  • 55,884
  • 29
  • 169
  • 223
Gijo Varghese
  • 11,264
  • 22
  • 73
  • 122

3 Answers3

4

Disable the IQKeyboardManager for your ViewController.

for that,

IQKeyboardManager.sharedManager().disableInViewControllerClass(ViewController.self)

And In that viewController write the following code. It will move your view up as per keyboard height

override func viewDidLoad() {
        super.viewDidLoad()

        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

}

func keyboardWillShow(notification: NSNotification) {

        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            if self.view.frame.origin.y == 0 {
                self.view.frame.origin.y -= keyboardSize.height
            }
        }
}

func keyboardWillHide(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            if self.view.frame.origin.y != 0 {
                self.view.frame.origin.y += keyboardSize.height
            }
        }
}

Now you want your "HEADER" view remain on TOP then,

Do like this :

**

YourViewController.view -> [headerView][contentView]

**

Put textfield in [contentView] And change [contentView].y instead of Self.view in above code.

Zaporozhchenko Oleksandr
  • 4,660
  • 3
  • 26
  • 48
Wolverine
  • 4,264
  • 1
  • 27
  • 49
4

Disable the IQKeyboardManager for your viewController:

override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        IQKeyboardManager.sharedManager().enable = false

        NotificationCenter.default.addObserver(self, selector: #selector(Login.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(Login.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

Handle keyboard:

func keyboardWillShow(notification: NSNotification) {

        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            if self.view.frame.origin.y == 0{
            self.table_view.frame.origin.y -= keyboardSize.height
            }
        }
    }

func keyboardWillHide(notification: NSNotification) {
        if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
            if self.view.frame.origin.y != 0{
            self.table_view.frame.origin.y += keyboardSize.height
            }
        }
    }

Remove observer:

override func viewWillDisappear(animated: Bool) {
        IQKeyboardManager.sharedManager().enable = true
        NSNotificationCenter.defaultCenter().removeObserver(self)    
    }
Bhavin Ramani
  • 3,221
  • 5
  • 30
  • 41
0

Answers from @Wolverine and @Bhavin Ramani were great: the best way to keep your custom header staying at top is to manually handle your keyboard (according to IQKeyboardSwift author's comment). If you use iOS default navigation bar, it seems it's handled for you by the library.

Here I just want to share some updates on this topic, for my future reference, as the answers are a bit old and some Swift syntax has changed. Code below is written in Xcode 13.2, targeting iOS 13+.

Firstly, you want to disable KQKeyboardManager by doing

IQKeyboardManager.shared.enable = false

Please note this lines only disables moving text field up feature, other IQKeyboard features such as resign on touch outside, auto tool bar, and etc., are not disabled by this line, this is usually what you want.

Then, you register keyboard events observer in view controller's viewDidLoad, remove observers in deinit.

    override func viewDidLoad() {
        super.viewDidLoad()

        IQKeyboardManager.shared.enable = false

        NotificationCenter.default.addObserver(self,
                                               selector: #selector(keyboardWillShow),
                                               name: UIResponder.keyboardWillShowNotification,
                                               object: nil)
        
        NotificationCenter.default.addObserver(self,
                                               selector: #selector(keyboardWillHide),
                                               name: UIResponder.keyboardWillHideNotification,
                                               object: nil)
    }

    deinit {
        IQKeyboardManager.shared.enable = true
        NotificationCenter.default.removeObserver(self)
    }

Next, add view moving up/down methods for keyboard show/hide.

    @objc private func keyboardWillShow(notification: NSNotification) {     
        if let keyboardSize = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect {
            print("keyboardSize.height", keyboardSize.height)
            // using the right key here is important, because 
            // keyboardFrameEndUserInfoKey is an user info key 
            // to retrieve the keyboard’s frame at the END of its animation.

            // here you move up the views you need to move up
            // if you use auto layout, update the corresponding constraints
            // or you update the views' frame.origin.y
            // you may want to do the updates within a 0.25s animation
        }
    }

    @objc private func keyboardWillHide(notification: NSNotification) {
        if let keyboardSize = notification.userInfo?[UIResponder.keyboardFrameBeginUserInfoKey] as? CGRect {
            // reset views to their original position on keyboard dismiss
        }
    }

You may also want to enable/disable auto tool bar, as it could make your keyboard height unstable.

// in viewDidLoad set to false, in deinit set back to true (if you need it)
IQKeyboardManager.shared.enableAutoToolbar = false
Daniel Hu
  • 423
  • 4
  • 11