3

Problem Statement : I have Nib file of UIView contains UIScrollview, In scrollview I have several TextFields and a TextView at the Bottom. What I want is to scroll upward when textfield or Textview starts editing.

What I tried :

In custome Method

NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil) 

I am calling this method parent view.

Notification Handling:

func keyboardWasShown(notification: NSNotification) { var userInfo = notification.userInfo! var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue keyboardFrame = self.convert(keyboardFrame, from: nil) var contentInset:UIEdgeInsets = self.mainScroll.contentInset contentInset.bottom = keyboardFrame.size.height self.mainScroll.contentInset = contentInset } 

This is working perfectly for UITextFields, But not working UITextView. Any idea where is the mistake.

PS: I have set the Delegates of UITextField and UITextView as well.

Any help will be much appreciated.

7
  • 1
    you can use contentoffset for scroll the scrollview. Commented Mar 20, 2017 at 8:48
  • Use the github.com/hackiftekhar/IQKeyboardManager, which automatically detect the textField or textView and accordingly manage all the keyboard handling. Commented Mar 20, 2017 at 8:55
  • 1
    @ZahidShabbir : The scrollview is not scrolling up or scrolling a little in case of textview? Commented Mar 20, 2017 at 9:18
  • 1
    @zahidshabbir : Have you tried using contentOffset ? Commented Mar 20, 2017 at 9:54
  • 1
    @zahidshabbir Please look at below answer. Commented Mar 20, 2017 at 10:14

3 Answers 3

1

Replace keyboardWasShown function with the below function :

 func keyboardWasShown(notification: NSNotification) { var userInfo = notification.userInfo! var keyboardFrame:CGRect = (userInfo[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue keyboardFrame = self.convert(keyboardFrame, from: nil) self.mainScroll.contentOffset = CGPoint(x: 0, y: keyboardFrame.size.height - Any number that fits your need.) } 

In keyBoardWillHide :

self.mainScroll.contentOffset = CGPoint(x: 0, y: 0) 

Hope it will help. Happy Coding!

Sign up to request clarification or add additional context in comments.

Comments

1

Demo link : https://github.com/harshilkotecha/UIScrollViewWhenKeyboardAppearInSwift3

when you have multiple textview it is so difficult so best solution ->

step 1 : add UITextFieldDelegate

class ScrollViewController: UIViewController,UITextFieldDelegate { 

step 2 :create new IBOutlet but don't connect with any text field

// get current text box when user Begin editing @IBOutlet weak var activeTextField: UITextField? 

step 3 : write this two method when user focus on text filed object pass the reference and store in activeTextField

// get current text field func textFieldDidBeginEditing(_ textField: UITextField) { activeTextField=textField; } func textFieldDidEndEditing(_ textField: UITextField) { activeTextField=nil; } 

step 5 : set Notification in viewdidload setNotificationKeyboard

override func viewWillAppear(_ animated: Bool) { // call method for keyboard notification self.setNotificationKeyboard() } // Notification when keyboard show func setNotificationKeyboard () { NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: .UIKeyboardWillShow, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: .UIKeyboardWillHide, object: nil) } 

step 6 : two methods for hide and show keyboard

func keyboardWasShown(notification: NSNotification) { var info = notification.userInfo! let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height+10, 0.0) self.scrollView.contentInset = contentInsets self.scrollView.scrollIndicatorInsets = contentInsets var aRect : CGRect = self.view.frame aRect.size.height -= keyboardSize!.height if let activeField = self.activeTextField { if (!aRect.contains(activeField.frame.origin)) { self.scrollView.scrollRectToVisible(activeField.frame, animated: true) } } } // when keyboard hide reduce height of scroll view func keyboardWillBeHidden(notification: NSNotification){ let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0,0.0, 0.0) self.scrollView.contentInset = contentInsets self.scrollView.scrollIndicatorInsets = contentInsets self.view.endEditing(true) } 

Comments

0

Swift 5

NotificationCenter.default.addObserver(self, selector: #selector(keyboardNotification), name: UIResponder.keyboardDidChangeFrameNotification, object: nil) @objc func keyboardNotification(_ notification: Notification) { if let userInfo = (notification as NSNotification).userInfo { let endFrame = (userInfo[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue let duration:TimeInterval = (userInfo[UIResponder.keyboardAnimationDurationUserInfoKey] as? NSNumber)?.doubleValue ?? 0 let animationCurveRawNSN = userInfo[UIResponder.keyboardAnimationCurveUserInfoKey] as? NSNumber let animationCurveRaw = animationCurveRawNSN?.uintValue ?? UIView.AnimationOptions().rawValue let animationCurve:UIView.AnimationOptions = UIView.AnimationOptions(rawValue: animationCurveRaw) if (endFrame?.origin.y)! >= UIScreen.main.bounds.size.height { scrollViewBottomConstraint?.constant = 0 } else { if tabBarController?.tabBar.frame == nil { return } scrollViewBottomConstraint?.constant = endFrame!.size.height - (tabBarController?.tabBar.frame.height)! let bottomOffset = CGPoint(x: 0, y: 0) scrollView.setContentOffset(bottomOffset, animated: true) } UIView.animate(withDuration: duration, delay: 0, options: animationCurve, animations: { self.view.layoutIfNeeded() }, completion: nil) } } 

usage:

1.connect the scrollView outlet to your controller and set its name to 'scrollView' 2.connect the scrollView bottom constraint to your controller & set its name to 'scrollViewBottomConstraint' 3.put the notification observer to your ViewDidLoad function. 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.