0

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.

Mr_Vlasov
  • 515
  • 2
  • 6
  • 25

1 Answers1

1

// declare a uitextfield which holds your activetextfiled

var activeTextField:UITextField!

// add keyboard dismiss tap gesture in your viewdidload

override func viewDidLoad() {
    super.viewDidLoad()   
 keyboardDismissTapGesture = UITapGestureRecognizer(target: self,                                                           action:      #selector(self.dismissKeyboard))     
}

// set active text field in textfield did begin delegte

func textFieldDidBeginEditing(textField: UITextField) {
activeTextField  = textField

    }

func textFieldDidEndEditing(textField: UITextField) {

  activeTextField  = nil
}

// dismiss keyboard for the activeTextField

func dismissKeyboard(){
   activeTextField.resignFirstResponder()
}

// adjust scrollview content size when keyboard will show

func keyboardWillShow(notification:NSNotification){

    var userInfo = notification.userInfo!
    var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).CGRectValue()
    keyboardFrame = self.view.convertRect(keyboardFrame, fromView: nil)

    var contentInset:UIEdgeInsets = self.scrollView.contentInset
    contentInset.bottom = keyboardFrame.size.height
    self.scrollView.contentInset = contentInset
}

// reset scrollview when keyboard will go

func keyboardWillHide(notification:NSNotification){

    let contentInset:UIEdgeInsets = UIEdgeInsetsZero
    self.scrollView.contentInset = contentInset
}
phil.nic
  • 35
  • 8
Anshad Rasheed
  • 2,526
  • 1
  • 14
  • 32