Michael Pangburn
Michael Pangburn

Reputation: 281

IQKeyboardManager - Shifting UITextView up too far

I'm using IQKeyboardManager to make keyboard management simple for a notes view controller I have (contains a large UITextView). Once the keyboard is active, however, the screen is shifted up unnecessarily. I'd like for the screen to stay how it is before the keyboard is active (see image below), and only have the UITextView scroll once the user's typing would be covered by the keyboard.

Before keyboard is active

When the keyboard is active (view scrolled up, covering "Notes" and Navigation Bar)

I don't want the Navigation Bar or the "Notes" label to be covered up, but I couldn't find a setting in IQKeyboardManager to stop the UITextView from being pushed all the way to the top.

How can I prevent the view from shifting up so far when the keyboard is made active?

EDIT: I should note that I'm not opposed to removing IQKeyboardManager, I just thought it would make dealing with this either. I mainly just need a way for my UITextView to automatically scroll when the user types something that would go underneath the keyboard.

UPDATE: I solved my problem without IQKeyboardManager by adjusting the contentInset of my UITextView depending on whether or not the keyboard is visible.

Upvotes: 5

Views: 2354

Answers (3)

Hamza Hasan
Hamza Hasan

Reputation: 1398

It's 2024 and this issue still exists.

As Michael Pangburn said that it keeps the screen but also stop UITextField or UITextView from scrolling and it is going behind the Keyboard.

First do as Oleh Zayats suggested, most probably in AppDelegate

IQKeyboardManager.sharedManager().enable = true
IQKeyboardManager.sharedManager().disabledDistanceHandlingClasses = [YourViewController.self]

For that you can implement Keyboard Notification Observers like,

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

deinit {
    NotificationCenter.default.removeObserver(self)
}

@objc func keyboardWillShow(notification: Notification) {
    if let userInfo = notification.userInfo,
       let keyboardFrame = userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect,
       let animationDuration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double {
        UIView.animate(withDuration: animationDuration) {
            
            if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
                let screenHeight = UIScreen.main.bounds.height
                let remainingSpace = screenHeight - keyboardSize.height
                let keyboardHeight = remainingSpace / 2 - self.view.frame.height / 2
                self.bottomConstraint.constant = <ORIGINAL CONSTRAINT CONSTANT> + abs(keyboardHeight)
                self.view.layoutIfNeeded()
            }
        }
    }
}

@objc func keyboardWillHide(notification: Notification) {
    if let userInfo = notification.userInfo,
       let animationDuration = userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? Double {
        UIView.animate(withDuration: animationDuration) {
            self.bottomConstraint.constant = <ORIGINAL CONSTRAINT CONSTANT>
            self.view.layoutIfNeeded()
        }
    }
}

Where self.bottomConstraint is the bottom constraint of UITextField or UITextView and or it's parent view, it depends.

Also you can also adjust the changing values, like may be you want to add or subtract something from abs(keyboardHeight) to meet your requirements.

Hope this will help you

Upvotes: 0

Oleh Zayats
Oleh Zayats

Reputation: 2443

If you want the screen to stay how it was you can disable the movement behavior for your class with IQKeyboardManager.sharedManager().disabledDistanceHandlingClasses property for example:

/* Probably in your AppDelegate where you setup the keyboard */

IQKeyboardManager.sharedManager().enable = true
IQKeyboardManager.sharedManager().disabledDistanceHandlingClasses = [YourViewController.self]

Upvotes: 0

Dawid Koncewicz
Dawid Koncewicz

Reputation: 141

Is you navigation bar translucent? It's common bug in IQKeyboardManager. Try to uncheck "Translucent" property in navigation bar. It's not perfect solution but should works.

Upvotes: 2

Related Questions