Reputation: 811
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
Reputation: 1136
One of the easy and no code of line solution is to use the following pods in your app.
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
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.
After that, simply select your scrollView in XIB and change its class to TPKeyboardAvoidingScrollView
as showing below.
Upvotes: 2
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
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
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