There are several similar questions on SO but non addresses the issue below.
I'm working on a simple login view with just 2 textFields for email and password. The best UX is when a user taps one of the textFields, the keyboard pops in, and the view moves up, while becoming a scrollView. This way, a user can still see what other UI elements are on the screen. User should also be able to hide the keyboard by swiping down. (Instagram and other big boys have this implemented)
I was able to built a view without a scrollView and dismiss the keyboard by resignFirstResponder:
class SignInVC: UIViewController, UITextFieldDelegate {
@IBOutlet weak var pwdField: UITextField!
@IBOutlet weak var emailField: UITextField!
@IBOutlet weak var scrollView: UIScrollView!
var keyboardDismissTapGesture: UIGestureRecognizer?
func dismissKeyboard(sender: AnyObject) {
pwdField?.resignFirstResponder()
emailField?.resignFirstResponder()
}
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.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
}
}
if keyboardDismissTapGesture == nil
{
keyboardDismissTapGesture = UITapGestureRecognizer(target: self,
action: #selector(self.dismissKeyboard))
self.view.addGestureRecognizer(keyboardDismissTapGesture!)
}
}
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
}
}
if keyboardDismissTapGesture != nil
{
self.view.removeGestureRecognizer(keyboardDismissTapGesture!)
keyboardDismissTapGesture = nil
}
}
override func viewWillDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self)
super.viewWillDisappear(animated)
}
I was trying to play around with scrollView.contentSize
trying to also move its origin:
scrollView.frame.origin.y -= keyboardSize.height
or its contentSize:
scrollView.contentSize = CGSize(width: self.view.frame.width, height: self.view.frame.height - keyboardSize.height)
but nothing worked.
Regarding the keyboard's ability to be swiped down, there was information that in scrollView's attribute inspector, I could change the "Keyboard" property to "Dismiss Interactively". Didn't work.