There is a very common but tricky part comes while handling textfields position when keyboard appears. Its sometimes become headache for developers to handle such small but tricky issue. When keyboard appears then some textfields get covered and user can’t see while editing it.
There are some solutions to handle this but many of them works only for the first time. And then doesn’t work.
I have found one best solution and it works great always and I have modified this code to work on Swift 4. I have used XCode 9.1 for this tutorial code.
Lets do it.
You will have to create new project to try this. Design your storyboard like the image from below link.
https://drive.google.com/a/nanostuffs.com/file/d/1KXJV49BP07T2q8nca4vKlz3eMU7xtkNG/view?usp=sharing
And set delegate of all textFields to ViewController.
Now in your ViewController class you can use it like below
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var myScrollView: UIScrollView!
@IBOutlet weak var constraintContentHeight: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewWillAppear(_ animated:Bool) {
super.viewWillAppear(animated)
//1 Add this observers to observe keyboard shown and hidden events
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(aNotification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(aNotification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
//2 Remove the observers added for keyboard from your ViewController
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
}
var activeField: UITextField?
// MARK: – UITextField Delegates
//3 ViewController activeField is an object of UITextField which will be used to manage and resign current active textField
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
func textFieldDidBeginEditing(_ textField: UITextField) {
activeField = textField
}
func textFieldDidEndEditing(_ textField: UITextField) {
activeField = nil
}
// Called when the UIKeyboardWillHide is sent
//4 This method is called from selector. So it requires @objc keyword and this method will adjust your scrollView (here myScrollView ?) and textFields to show as original.
@objc func keyboardWillBeHidden(aNotification: NSNotification) {
let contentInsets: UIEdgeInsets = .zero
self.myScrollView.contentInset = contentInsets
self.myScrollView.scrollIndicatorInsets = contentInsets
}
// Called when the UIKeyboardWillShow is sent
//5
This method will adjust your scrollView and will show textFields above the keyboard.
@objc func keyboardWillShow(aNotification: NSNotification) {
var info = aNotification.userInfo!
let kbSize: CGSize = ((info[“UIKeyboardFrameEndUserInfoKey”] as? CGRect)?.size)!
print(“kbSize = \(kbSize)”)
let contentInsets: UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0)
myScrollView.contentInset = contentInsets
myScrollView.scrollIndicatorInsets = contentInsets
var aRect: CGRect = self.view.frame
aRect.size.height -= kbSize.height
if !aRect.contains(activeField!.frame.origin) {
self.myScrollView.scrollRectToVisible(activeField!.frame, animated: true)
}
}
} // Class End