Reputation: 1
I've implemented some code to scroll the screen when the keyboard is displayed so as to prevent fields from being covered.
This is working fine for Text fields however it's not working for a UITextView field.
Here is the code I've implemented:
func textFieldDidBeginEditing(textField: UITextField)
{
//print("textfieldDidBeginEditing")
activeField = textField
}
func textFieldDidEndEditing(textField: UITextField)
{
//print("textfieldDidEndEditing")
activeField = nil
}
func textViewDidBeginEditing(textView: UITextView) {
print("textViewDidBeginEditing")
//print(textView)
activeTextView = textView
print("1activeTextView:\(activeTextView)")
}
func textViewDidEndEditing(textView: UITextView) {
print("textViewDidEndEditing")
//print(textView)
//print("2activeTextView:\(activeTextView)")
activeTextView = nil
}
func registerForKeyboardNotifications()
{
//Adding notifies on keyboard appearing
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWasShown:", name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardWillBeHidden:", name: UIKeyboardWillHideNotification, object: nil)
}
func deregisterFromKeyboardNotifications()
{
//Removing notifies on keyboard appearing
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}
func keyboardWasShown(notification: NSNotification)
{
print("yes")
//Need to calculate keyboard exact size due to Apple suggestions
self.scrollView.scrollEnabled = true
let info : NSDictionary = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize!.height, 0.0)
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
var aRect : CGRect = self.view.frame
aRect.size.height = keyboardSize!.height
if (activeField != nil) {
print("KWSactivfield:\(activeField)")
if (!CGRectContainsPoint(aRect, activeField!.frame.origin))
{
print("!CGRectContainsPoint")
self.scrollView.scrollRectToVisible(activeField!.frame, animated: true)
}
}
if (activeTextView != nil) {
print("KWSactiveTextView:\(activeTextView)")
if (!CGRectContainsPoint(aRect, activeTextView!.frame.origin))
{
print("true4")
self.scrollView.scrollRectToVisible(activeTextView!.frame, animated: true)
}
}
}
func keyboardWillBeHidden(notification: NSNotification)
{
//Once keyboard disappears, restore original positions
let info : NSDictionary = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.CGRectValue().size
let contentInsets : UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, -2*keyboardSize!.height, 0.0)
print("insets")
self.scrollView.contentInset = contentInsets
self.scrollView.scrollIndicatorInsets = contentInsets
self.view.endEditing(true)
self.scrollView.scrollEnabled = false
}
I've noticed is that activeTextView is always "nil" once inside the keyboardWasShown function.
Any help would be much appreciated as I can't seem to figure this out.
Thanks!
Upvotes: 0
Views: 168
Reputation: 2947
i know this is an old post but i had the same problem and i solved it with a little trick. I post here my solution that could be helpful for someone else.
The trick is to assign a value to tag property of all my textviews and then in my keyboardWasShown method read it and, depending on this value, i know which textview was selected. Some codes will help you to understand what i did:
i declared my textviews and an int variable to store the tag value of selected textview:
var myTextViewField: UITextView! = nil
var anotherTextViewField: UITextView! = nil
var activeTextViewTag: Int = 0
in viewDidLoad with all the other properties i've set tag property of my textviews:
myTextViewField.tag = 1
anotherTextViewField.tag = 2
now it's time to read the tag value and i did it in textViewDidBeginEditing method
func textViewDidBeginEditing(_ textView: UITextView) {
activeTextViewTag = textView.tag
}
In the end, in keyboardWasShown method read the activeTextViewTag value and move the scrollview
func keyboardWasShown(notification: NSNotification){
print("keyboardWasShown")
if let userInfo = notification.userInfo {
if let keyboardSize = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
let contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: keyboardSize.height, right: 0)
scrollView.contentInset = contentInsets;
scrollView.scrollIndicatorInsets = contentInsets;
// If active text field is hidden by keyboard, scroll it so it's visible
var aRect: CGRect = self.view.frame
aRect.size.height = aRect.size.height - keyboardSize.height
var activeField: UITextView! = nil
if(activeTextViewTag == 1){
activeField = myTextViewField
} else {
activeField = anotherTextViewField
}
if(!aRect.contains(activeField.frame.origin)){
self.scrollView.scrollRectToVisible(activeField.frame, animated: true)
}
} else {
// no UIKeyboardFrameBeginUserInfoKey entry in userInfo
print("no UIKeyboardFrameBeginUserInfoKey entry in userInfo")
}
} else {
// no userInfo dictionary in notification
print("no userInfo dictionary in notification")
}
}
I checked the active field directly in keyboardWasShown but it could be done in a separated method. That's all! This solution perfectly worked for me, i hope this can help someone else!
Upvotes: 1