iOS Swift UIScrollView move content under the Keyboard into the view

Most of the time we will be facing an issue where some UITextFields near the bottom of the content view will get blocked when the keyboard pops up, as it blocks the bottom half of our screen; we cannot see what we are typing.Hell....... But the good thing is, the scroll view allows us to scroll the content into view.

How about moving the blocked content to the view automatically? Now we will do that with a simple work around.

First we have to check which UITextField is currently being focused. You can do this many different ways, but I chose to add the view controller as a delegate to the UITextFields. In interface builder Ctrl – Drag from each UITextField to the view controller and set it as the delegate.

Next we have to implement couple of delegate methods to solve our problem

Copy the below magic lines to your Swift file.

weak var activeTextField: UITextField?

func textFieldDidEndEditing(textField: UITextField) {  
    self.activeField = nil
}

func textFieldDidBeginEditing(textField: UITextField) {  
    self.activeField = textField
}

Now we need to register for keyboard notifications. In the viewDidLoad function, add the view controller as an observer.

Do not forget to unregister from these events when you are transitioning/navigating away from your view controller.

NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardDidShow:", name: UIKeyboardDidShowNotification, object: nil)

NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil)  

Finally, add an outlet to your scroll view and implement the keyboard notification selectors.
Courtesy: iOS Developer Library.

func keyboardDidShow(notification: NSNotification) {  
    if let activeField = self.activeField, keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
        let contentInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardSize.height, right: 0.0)
        self.scrollView.contentInset = contentInsets
        self.scrollView.scrollIndicatorInsets = contentInsets
        var aRect = self.view.frame
        aRect.size.height -= keyboardSize.size.height
        if (!CGRectContainsPoint(aRect, activeField.frame.origin)) {
            self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
        }
    }
}

func keyboardWillBeHidden(notification: NSNotification) {  
    let contentInsets = UIEdgeInsetsZero
    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets
}

How it is done is as important as having it done :)

Sajeel

Read more posts by this author.

Subscribe to The Magics

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!