1

I understand that the issue I'm posting has been discussed a lot but as far as I have searched in SO, I couldn't find a solution specific to my issue. I'm posting this to get some inputs.

Problem:

View hierarchy: View -> ScrollView -> View -> Textfield

I have implemented two screens with multiple textfields laid on top of a scrollview to avoid keyboard obscuring the textfield when its at the bottom of the page. I have achieved this using the sample code provided by Apple with minor modifications.

  1. Subscribe to UIKeyboardWillShowNotification and UIKeyboardWillHideNotification
  2. When keyboard is shown, get the height of the keyboard from userInfo dictionary and set appropriate content inset to move the textfield above the Keyboard
  3. When keyboard is hidden, set the content inset to UIEdgeInsetZero to bring back to normal size

The above implementation works perfectly fine when there are more textfields that could occupy the entire screen (assume there are 10 textfields and they extend beyond the frame of the the scroll view). Whenever I tap on a textfield, it moves above the keyboard as expected and I can also scroll the page till the bottom most textfield is visible above the keyboard frame (when the keyboard is still up).

My problem arises when I have only two textfield in the scrollview that are centered vertically in the screen. When I tap on a textfield, the scrollview get an inset equivalent to the keyboard height and it moves above the keyboard as expected but when I scroll the screen, I could see a huge blank space (due to the additional inset) below the textfields.

How can I avoid that blank space when there are only one or two textfields in the page? Should I have to write a different logic to handle that scenario? Any help would be appreciated.

Below is the code:

    override func viewDidLoad() {
        super.viewDidLoad()

        NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillShow:", name: UIKeyboardWillShowNotification, object: nil)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillHide:", name: UIKeyboardWillHideNotification, object: nil)
    }


    func keyboardWillShow(notification: NSNotification) {
        if let userInfo = notification.userInfo {
            let keyboardFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.CGRectValue()
            if let kbFrame = keyboardFrame {

                let inset = CGRectGetHeight(kbFrame)
                scrollView.contentInset = UIEdgeInsetsMake(0, 0, inset, 0)
                scrollView.scrollIndicatorInsets = UIEdgeInsetsMake(0, 0, inset, 0)
            }
        }
    }

    func keyboardWillHide(notfication: NSNotification) {
        scrollView.contentInset = UIEdgeInsetsZero
        scrollView.scrollIndicatorInsets = UIEdgeInsetsZero
    }
TMDB
  • 11
  • 2

2 Answers2

1

TPKeyboardAvoidingScrollView is good, but i recently switched to IQKeyboardManager -> https://github.com/hackiftekhar/IQKeyboardManager

Its upto you to choose but i prefer IQKeyboardManager cause its easy

Sanjan Piya
  • 247
  • 2
  • 8
  • Do you find it better or just the fact that you call it once versus not having to set the classes you want to use it with? – sschale Feb 28 '16 at 09:19
0

There are a number of solutions out there, but my preferred solution is to use TPKeyboardAvoiding. To use it here you would just make your UIScrollView an instance or subclass of TPKeyboardAvoidingScrollView in SB or code and it should care of the rest, no other code required!

sschale
  • 5,168
  • 3
  • 29
  • 36
  • Thanks. I will take a look at the solution but I would like to do it myself and learn from the process. I can go through the code in the tool but any solution to implement it? – TMDB Feb 28 '16 at 09:12
  • You can do that, and you're more than welcome to, but it's a house of pain which I tried to do and failed. – sschale Feb 28 '16 at 09:18