30542

Move View when keyboard appears and present it in a scrollView. Swift 3

Question:

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.

Answer1:

// 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 }

Recommend

  • How recognize which UIImageview I've tapped?
  • iPad - Dismiss keyboard for modal view controller in UIModalPresentationFormSheet mode
  • how to list active gesture recognizers?
  • Detecting shakes in sprite kit
  • Using multiple UIGestureRecognizers simultaneously like UIRotationGestureRecognizer & UIPanGestu
  • UIPinchGestureRecognizer only for pinching out
  • How to remove panGesture after touch in swift
  • How to access UIViewController's varaibles inside “func applicationWillResignActive”? Swift, iO
  • Auto Height of UICollectionView inside UITableViewCell
  • Convert Func to Func
  • Custom Nav Title offset ios 11
  • How to pass a value from ASP.NET MVC controller to ASP.NET webforms control inside MVC View?
  • Application level floating views with navigation in Android
  • ASP.NET MVC Application won't update some controllers
  • android.support.v7.widget.Toolbar VectorDrawableCompat IllegalStateException when using support lib
  • How can I enlarge video fullscreen without the affected interface project in as3?
  • Webgrid not refreshing after delete MVC
  • GridView breaks while scrolling
  • Custom Tabgroup Appcelerator
  • Functions in global context
  • Disable Enter in editText android
  • Android fill_parent issue
  • NHibernate Validation Localization with S#arp Architecture
  • Control modification in presentation layer
  • how to do an event when i swipe from fragment to the other
  • Email format validation in mvc3 view
  • Update CALayer sublayers immediately
  • Projection media query: browser support and workarounds?
  • Android screen density dpi vs ppi
  • Deselecting radio buttons while keeping the View Model in synch
  • JFileChooser in front of fullscreen Swing application
  • Deleting and Updating values from a cusrsor adapter
  • How to apply VCL Styles to DLL-based forms in Inno Setup?
  • Cannot Parse HTML Data Using Android / JSOUP
  • How get height of the a view with gone visibility and height defined as wrap_content in xml?
  • Getting Messege Twice Using IMvxMessenger
  • unknown Exception android
  • XCode 8, some methods disappeared ? ex: layoutAttributesClass() -> AnyClass
  • failed to connect to specific WiFi in android programmatically
  • How to load view controller without button in storyboard?