Jeesson_7
Jeesson_7

Reputation: 811

How do we make keyboard appear below textView in swift?

I have done keyboard appearing below textfield using

on View did Load adding a observer()

    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(Gold_Loan_First_ViewController.keyboardDidShow(_:)), name: UIKeyboardDidShowNotification, object: nil)

    NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(Gold_Loan_First_ViewController.keyboardWillBeHidden(_:)), name: UIKeyboardWillHideNotification, object: nil)

And then updating the frame

weak var activeField: UITextField?

func textFieldDidEndEditing(textField: UITextField) {
    self.activeField = nil


}
func textField(textField: UITextField, shouldChangeCharactersInRange range: NSRange, replacementString string: String) -> Bool {
    if textField==txtOTP {
        txtOTP.errorMessage=""
    }
  return true
}
func textFieldDidBeginEditing(textField: UITextField) {
    self.activeField = textField

}




func keyboardDidShow(notification: NSNotification)
{
    if let activeField = self.activeField,
        let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue() {
        let contentInsets = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardSize.height, right: 0.0)
        self.scrollView.contentInset = contentInsets
        self.scrollView.scrollIndicatorInsets = contentInsets
        var aRect = self.view.frame
        aRect.size.height -= keyboardSize.size.height
        if (!CGRectContainsPoint(aRect, activeField.frame.origin)) {
            self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
        }
    }


}

func keyboardWillBeHidden(notification: NSNotification)
{
    let contentInsets = UIEdgeInsetsZero
    self.scrollView.contentInset = contentInsets
    self.scrollView.scrollIndicatorInsets = contentInsets
}

But how do I do it for a textView. I tried the same code with didBeginEditing of textView with no positive effect

Upvotes: 7

Views: 4458

Answers (5)

Sucharu Hasija
Sucharu Hasija

Reputation: 1136

One of the easy and no code of line solution is to use the following pods in your app.

IQKeyboardManger

Later you need to just import that in App Delegate and add this two lines of code in didfinishLaunching method:

  IQKeyboardManager.sharedManager().enable = true

Your problem will be solved for whole app.

For Swift 5:

IQKeyboardManager.shared.enable = true

Upvotes: 6

Prince Kumar Sharma
Prince Kumar Sharma

Reputation: 12641

You can simply use TPKAScrollViewController.h & TPKAScrollViewController.m files by using Bridging Header.

While dragging these objective-C file to your swift project, it will automatically ask for Create Bridging. Create Bridging Header and Import #import "TPKAScrollViewController.h" to YourApp-Bridging-Header.h file.

enter image description here

After that, simply select your scrollView in XIB and change its class to TPKeyboardAvoidingScrollView as showing below.

enter image description here

Upvotes: 2

Pramod Kumar
Pramod Kumar

Reputation: 2662

Find the correct height of keyboard and assign it to the bottom constraint of the textView or reduce the y position of textView. Like:

Step-1: make a property keyboardHeight in you viewController.

var keyboardHeight: CGFloat = 0.0

Step-2: Make @IBOutlet of bottom constraint of the textView.

@IBOutlet weak var textViewBottomConstraint: NSLayoutConstraint!

Step-3:

fileprivate func addKeyboardNotification() {
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

fileprivate func removeKeyboardNotification() {
    IQKeyboardManager.shared().isEnabled = true
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
    NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}

Copy & paste these functions to your view controllers, and call self.addKeyboardNotification() in viewDidLoad() and of you viewController

Step-4:

deinit {
    self.removeKeyboardNotification()
}

also add this code to your viewController.

Step-5:

    func keyboardWillShow(_ notification: Notification) {
    if let keboardFrame = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue, self.keyboardHeight <= 0.0 {
        self.keyboardHeight = keboardFrame.height + 45.0 //(Add 45 if your keyboard have toolBar if not then remove it)
    }

    UIView.animate(withDuration: 0.3, animations: {
        self.textViewBottomConstraint.constant = self.keyboardHeight
    }, completion: { (success) in
    })
}

func keyboardWillHide(_ notification: Notification) {
    UIView.animate(withDuration: 0.3, animations: {
        self.textViewBottomConstraint.constant = 0.0
    }, completion: { (success) in
    })
}

That's it to manage the textView with keyboard. If you don't want to use textViewBottomConstraint the you can work with the y position of the textView.

Upvotes: 1

Codus
Codus

Reputation: 1473

Salman Ghumsani is Right.

Please change UIKeyboardFrameBeginUserInfoKey to UIKeyboardFrameEndUserInfoKey.

Apple Debeloper Document: Keyboard Notification User Info Keys

UIKeyboardFrameEndUserInfoKey

The key for an NSValue object containing a CGRect that identifies the ending frame rectangle of the keyboard in screen coordinates. The frame rectangle reflects the current orientation of the device.

UIKeyboardFrameBeginUserInfoKey

The key for an NSValue object containing a CGRect that identifies the starting frame rectangle of the keyboard in screen coordinates. The frame rectangle reflects the current orientation of the device.

Conclusion

So, if u use UIKeyboardFrameBeginUserInfoKey u might get the keyboard height to 0. Causing the system thought UITextView was not covered.

Upvotes: 1

swetansh kumar
swetansh kumar

Reputation: 475

I have gone through such a situation. For this first I added extension in my UiViewController :

    extension CCViewController : UITextViewDelegate {
        func textViewDidBeginEditing(_ textView: UITextView) {
            // write code as per your requirements
        }

        func textViewDidEndEditing(_ textView: UITextView) {
             // write code as per your requirements
        }

        func textViewDidChange(_ textView: UITextView) {
            self.p_adjustMessageFieldFrameForTextView(textView)
        }
    }

    // Defining the p_adjustMessageFieldFrameForTextView method

    fileprivate func p_adjustMessageFieldFrameForTextView(_ textView : UITextView) {
            var finalheight : CGFloat = textView.contentSize.height + 10
            var kMaxMessageFieldHeight : CGFloat = 50
            if  (finalheight > kMaxMessageFieldHeight) {
                finalheight = kMaxMessageFieldHeight;
            } else if (finalheight < kCommentTextViewHeight){
                finalheight = kCommentTextViewHeight;
            }

            scrollView!.view.frame = CGRect(x: 0, y: kNavBarHeight + statuBarHeight, width: SCREEN_WIDTH,height: SCREEN_HEIGHT - finalheight - keyboardRect!.size.height - kNavBarHeight - statuBarHeight)
// It is there for understanding that we have to calculate the exact frame of scroll view

            commentTextView!.frame = CGRect(x: 0, y: bottomOfView(scrollView!.view), width: SCREEN_WIDTH, height: finalheight)
            self.p_setContentOffsetWhenKeyboardIsVisible()
        }

    // Defining the p_setContentOffsetWhenKeyboardIsVisible method

    fileprivate func p_setContentOffsetWhenKeyboardIsVisible() {
            // here you can set the offset of your scroll view
        }

Also there is a method named bottomView() :

func bottomOfView(_ view : UIView) -> CGFloat {
        return view.frame.origin.y + view.frame.size.height
    }

Upvotes: 2

Related Questions