I have a loginView, inside that i have two textFields and a button. I have to move up the view while tapping on textField and move down the view when press the return key.
My problem is that it is working fine for all conditions but while tap on the one textField view is moving up but at same time when we go for next textField view is moving down.
import UIKit
class CheckFontIconView: UIViewController,UITextFieldDelegate {
var activeField: UITextField?
#IBOutlet weak var loginFieldsView: UIView!
#IBOutlet weak var label: UILabel!
#IBOutlet weak var mobileNo: UITextField!
#IBOutlet weak var textFieldPassword: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
mobileNo.delegate = self
textFieldPassword.delegate = self
registerForKeyboardNotifications()
}
#IBAction func btnLoginAction(_ sender: Any) {
}
deinit {
//NotificationCenter.default.removeObserver(self)
self.deregisterFromKeyboardNotifications()
}
func registerForKeyboardNotifications() {
//Adding notifies on keyboard appearing
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func deregisterFromKeyboardNotifications() {
//Removing notifies on keyboard appearing
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func keyboardWasShown(notification: NSNotification) {
//Need to calculate keyboard exact size due to Apple suggestions
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
if self.activeField != nil {
self.loginFieldsView.frame.origin.y -= (keyboardSize?.height)!
}
}
func keyboardWillBeHidden(notification: NSNotification) {
//Once keyboard disappears, restore original positions
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
self.loginFieldsView.frame.origin.y -= (keyboardSize?.height)!
self.loginFieldsView.endEditing(true)
}
func textFieldDidBeginEditing(_ textField: UITextField) {
self.activeField = textField
}
func textFieldDidEndEditing(_ textField: UITextField) {
self.activeField = nil
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
activeField?.resignFirstResponder()
return true
}
}
Once try with scrollView,I hope it will help you.
Use a scroll view to moving text field up and down.
Making Up
Make a #IBOutlet weak var scroller: UIScrollView!;
Under textFieldDidBeginEditing:textField method
Create a CGPoint with x: 0 and y texfield.frame.origin.y
And then start moving the scroller with setContentOffset:animated function.(Parameter will be your CGPoint and a boolean value true).
Making Down
Under textFieldDidEndEditing:textField set your scroller to CGPoint.zero with same setContentOffset:animated function.
*And your textFieldShouldReturn:textField should be resignFirstResponder or to next textField.
Please let me know if having any problem on this.
Thanks for ask question...
Use TPKeyboard to achieve above functionality then no manage this kind of stuff (Automatically manage by TPKeyboard)...
Update:
I think you have done some mistake in given below code...
func textFieldDidEndEditing(_ textField: UITextField) {
self.activeField = nil
}
You have to DEBUG and identify exact issue..
Happy coding...
I made the simple code for your problem. It is not good but you can refer with that idea for fix your problem.
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
var activeField: UITextField?
#IBOutlet weak var loginFieldsView: UIView!
#IBOutlet weak var label: UILabel!
#IBOutlet weak var mobileNo: UITextField!
#IBOutlet weak var textFieldPassword: UITextField!
var originalHeight:CGFloat!
override func viewDidLoad() {
super.viewDidLoad()
mobileNo.delegate = self
textFieldPassword.delegate = self
originalHeight = self.loginFieldsView.frame.origin.y
registerForKeyboardNotifications()
}
#IBAction func btnLoginAction(_ sender: Any) {
}
deinit {
//NotificationCenter.default.removeObserver(self)
self.deregisterFromKeyboardNotifications()
}
func registerForKeyboardNotifications() {
//Adding notifies on keyboard appearing
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWasShown(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func deregisterFromKeyboardNotifications() {
//Removing notifies on keyboard appearing
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
func keyboardWasShown(notification: NSNotification) {
//Need to calculate keyboard exact size due to Apple suggestions
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
if self.activeField != nil {
if self.loginFieldsView.frame.origin.y == originalHeight {
self.loginFieldsView.frame.origin.y -= (keyboardSize?.height)!
}
}
}
func keyboardWillBeHidden(notification: NSNotification) {
//Once keyboard disappears, restore original positions
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
if originalHeight > self.loginFieldsView.frame.origin.y {
self.loginFieldsView.frame.origin.y += (keyboardSize?.height)!
}
self.loginFieldsView.endEditing(true)
}
func textFieldDidBeginEditing(_ textField: UITextField) {
self.activeField = textField
}
func textFieldDidEndEditing(_ textField: UITextField) {
self.activeField = nil
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
activeField?.resignFirstResponder()
return true
}
}
Just one change hold your view old frame in a variable and assign it again to your view when keyboard disappear.
import UIKit
class CheckFontIconView: UIViewController,UITextFieldDelegate {
var activeField: UITextField?
#IBOutlet weak var loginFieldsView: UIView!
#IBOutlet weak var label: UILabel!
#IBOutlet weak var mobileNo: UITextField!
#IBOutlet weak var textFieldPassword: UITextField!
var previousFrame : CGRect!
override func viewDidLoad() {
super.viewDidLoad()
previousFrame=self.loginFieldsView.frame
mobileNo.delegate = self
textFieldPassword.delegate = self
registerForKeyboardNotifications()
}
func keyboardWasShown(notification: NSNotification) {
//Need to calculate keyboard exact size due to Apple suggestions
var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size
if self.activeField != nil {
self.loginFieldsView.frame.origin.y = previousFrame.origin.y-(keyboardSize?.height)!
}
}
func keyboardWillBeHidden(notification: NSNotification) {
//Once keyboard disappears, restore original positions
/*var info = notification.userInfo!
let keyboardSize = (info[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size*/
self.loginFieldsView.frame = previousFrame
//self.loginFieldsView.endEditing(true)
}
func textFieldDidBeginEditing(_ textField: UITextField) {
self.activeField = textField
}
func textFieldDidEndEditing(_ textField: UITextField) {
self.activeField = nil
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
activeField?.resignFirstResponder()
return true
}
}
Related
I have arranged views like below
I am getting gap like below Why?
when view is down it looks good, when i tap on textfield then total view goes up and when i scrool tableview i am getting gap between like below.
this is my code:
import UIKit
class ChatViewController: UIViewController, UITextFieldDelegate {
#IBOutlet weak var belowtextFieldHeightConstraint: NSLayoutConstraint!
#IBOutlet weak var catViewBottomConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboard(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboard(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
#objc func keyboard(notification:Notification) {
guard let keyboardReact = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else {
return
}
if notification.name == UIResponder.keyboardWillShowNotification || notification.name == UIResponder.keyboardWillChangeFrameNotification {
self.view.frame.origin.y = -keyboardReact.height
} else {
self.view.frame.origin.y = 0
}
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
Text fields have a property called inputAccessoryView, make sure you are not setting the view anywhere and that it is nil when the keyboard is invoked.
It looks like you have one set up.
I'm having a weird behavior from a keyboard. But only on one of the view controllers. I have another view controller with a UITextField and that one works charms (as soon as I press the return button it disappears). And the weird part is that that one isnt even setup at all. it only has becomefirstresponder on viewdidload and resignfirstresponder on viewwilldissapear.
THIS keyboard however, VIDEO OF NASTY KEYBOARD is quite the nasty booger.
NOTE: In the video I do the following:
* Tap the UITextfield
* Keyboard Appears (view shifts up)
* I type lol and then press send (nothing happens)
* I start tapping frantically all around the screen (except the UITextField)
* Keyboard dissapears
Here's the code for this View:
class ChatScreenVC: UIViewController, UITextFieldDelegate {
var gameDelegate: GameManagerDelegate?
var chatLogString: String = ""
var offsetY:CGFloat = 0
#IBOutlet weak var chatView: UIView!
#IBOutlet weak var closeBtn: UIButton!
#IBOutlet weak var titleBtn: UILabel!
#IBOutlet weak var chatLog: UITextView!
#IBOutlet weak var chatInput: UITextField!
#IBOutlet weak var sendBtn: UIButton!
#IBOutlet weak var viewCenterConstraint: NSLayoutConstraint!
#IBAction func inputTapped(_ sender: Any) {
chatInput.becomeFirstResponder()
}
#IBAction func closeTapped(_ sender: Any) {
self.dismiss(animated: true, completion: nil)
}
#IBAction func sendTapped(_ sender: Any) {
if chatInput.text != nil && chatInput.text != "" && chatInput.text != " " {
gameDelegate?.sendChat(message: chatInput.text!)
}
chatInput.text = ""
chatInput.resignFirstResponder()
self.view.endEditing(true)
}
#objc func keyboardWillShow(_ notification: Notification) {
if let keyboardFrame: NSValue = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue {
let keyboardRectangle = keyboardFrame.cgRectValue
let keyboardHeight = keyboardRectangle.height
viewCenterConstraint.constant = -keyboardHeight
}
}
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
print("THIS IS HAPPENING!")
chatInput.resignFirstResponder()
self.view.endEditing(true)
return true
}
#objc func keyboardWillHide(_ notification: Notification) {
if let keyboardFrame: NSValue = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue {
viewCenterConstraint.constant = 0
}
}
#objc func reloadData() {
chatLogString = (gameDelegate?.updateChatString())!
chatLog.text = chatLogString
}
override func viewDidLoad() {
super.viewDidLoad()
chatLog.text = chatLogString
chatLog.isEditable = false
chatInput.autocorrectionType = .no
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
setupView()
animateView()
}
override func viewWillDisappear(_ animated: Bool) {
chatInput.resignFirstResponder()
}
override func viewDidAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector: #selector(self.reloadData), name: Notification.Name(rawValue: SMACK_TALK), object: nil)
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)
}
override func viewDidDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self, name: Notification.Name(rawValue: SMACK_TALK), object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
}
}
Now before you go and tell me "not to use both the resignfirstresponder and the endediting(true)" I gotta clear out that I tried both individually and together and still don't get any response.
You can resign keyboard before sendChat(). I think it is sync call and it will block main thread for sometimes thats why this weird behaviour occurs.
chatInput.resignFirstResponder() before you are making API call.
#IBAction func sendTapped(_ sender: Any) {
if chatInput.text != nil && chatInput.text != "" && chatInput.text != " " {
chatInput.resignFirstResponder()
self.view.endEditing(true)
gameDelegate?.sendChat(message: chatInput.text!)
}
}
There are several TextFields in a UIView.I want move view up when user edit TextField.And then i try it reference Move view with keyboard using Swift
My core code is below:
//MARK: Properties
#IBOutlet weak var userAccountTextField: UITextField!
#IBOutlet weak var passwordTextField: UITextField!
#IBOutlet weak var confirmPasswordTextField: UITextField!
#IBOutlet weak var emailTextField: UITextField!
#IBOutlet weak var phoneTextField: UITextField!
//MARK: Callback
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: self.view.window)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillHide, object: self.view.window)
}
func keyboardWillShow(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size {
if self.view.frame.origin.y == 0{
//self.view.frame.origin.y -= keyboardSize.height
self.view.frame.origin.y -= 150
}
}
}
func keyboardWillHide(notification: NSNotification) {
if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue.size {
if self.view.frame.origin.y != 0{
//self.view.frame.origin.y += keyboardSize.height
self.view.frame.origin.y += 150
}
}
}
There are two issues:
1.The keyboardSize.height with hide the keyboard is bigger than keyboardSize.height with show the keyboard.Then there will be a black field top after the keyboard hide. So now i must use a constant number.
2.The view move up after the keyboard show, it's good.But the view move down again when i type some chars or i click other TextFiled.It's good If i put these TextFields into a ScrollView.But i don't it's why.Like below picture:
enter image description here
Any help would be greatly appreciated.
Your “viewDidLoad” method contains an error, you have to add and not to remove the observer, you have to remove it in “viewWillDisappear”
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillHide), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
Here is my code:
class TextViewController: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate{
#IBOutlet weak var chatTextField: UITextField!
#IBOutlet weak var SendButton: UIButton!
#IBOutlet weak var ChatField: UILabel!
#IBOutlet var keyboardHeightLayoutConstraint: NSLayoutConstraint?
var textView: UITextView! { return (view as! UITextView) }
override func loadView() {
let textView = UITextView(frame: UIScreen.main.bounds, textContainer: nil)
textView.alwaysBounceVertical = true
textView.keyboardDismissMode = .interactive
view = textView
}
deinit {
NotificationCenter.default.removeObserver(self)
}
override func viewDidLoad() {
super.viewDidLoad()
chatTextField.delegate = self
NotificationCenter.defaultCenter.addObserver(self, selector: #selector(TextViewController.keyboardWillShow(_:)), name: UIKeyboardWillShowNotification, object: nil)
}
func keyboardWillShow(notification: NSNotification) {
let frameEnd = (notification.userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let keyboardHeightEnd = view.convert(frameEnd, from: nil).size.height
}
//MARK: UITextFieldDelegate
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
func textFieldDidBeginEditing(_ textField: UITextField)
{
}
func textFieldDidEndEditing(_ textField: UITextField) {
ChatField.text=textField.text
}
But the compiler shows:
"Type TextViewController has no member keyboardWillShow"
Does anyone know how to solve this problem?
Sorry guys but I did have a func called keyboardWillShow. I update the whole code so you guys can see.'
Thanks again
You need to add keyboardWillShow method to your class:
func keyboardWillShow(notification: NSNotification) {
// Add your logic here.
}
You don't need to add TextViewController while using selector keyboardWillShow(_:). I ran your code with the following changes and it worked fine.
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
Hope it helps!
Bilawal is right, adding the class-name as a prefix before the method indicates you want to call it as a class method, while you have declared it as an instance-method.
And also in the keyboardWillShow method you are not doing anything to make the textfield change it's frame depending on keyboard position/height.
This is my whole code when keyboard appears it hides the top 1 textfield and one is half visible. It works but when it hiddes the top fields it looks to wired.
I found this code on net but i can't able to fix it.
class ViewController2: UIViewController, ENSideMenuDelegate, UITextFieldDelegate {
#IBOutlet weak var text1: UITextField!
#IBOutlet weak var text2: UITextField!
#IBOutlet weak var text3: UITextField!
#IBOutlet weak var text4: UITextField!
#IBOutlet weak var scrollview: UIScrollView!
var activeTextField: UITextField!
#IBOutlet weak var container_view: UIView!
override func viewDidLoad() {
super.viewDidLoad()
//Move next line to viewWillAppear functon if you store your view controllers
self.sideMenuController()?.sideMenu?.delegate = self
// Do any additional setup after loading the view.
self.text1.delegate = self
self.text2.delegate = self
self.text3.delegate = self
self.text4.delegate = self
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - ENSideMenu Delegate
func sideMenuWillOpen() {
println("sideMenuWillOpen")
}
func sideMenuWillClose() {
println("sideMenuWillClose")
}
func sideMenuDidClose() {
println("sideMenuDidClose")
}
func sideMenuDidOpen() {
println("sideMenuDidOpen")
}
/*
func sideMenuShouldOpenSideMenu() -> Bool {
println("sideMenuShouldOpenSideMenu")
return false
}
*/
// MARK: - Keyboard
// Call this method somewhere in your view controller setup code.
func registerForKeyboardNotifications() {
let notificationCenter = NSNotificationCenter.defaultCenter()
notificationCenter.addObserver(self,
selector: "keyboardWillBeShown:",
name: UIKeyboardWillShowNotification,
object: nil)
notificationCenter.addObserver(self,
selector: "keyboardWillBeHidden:",
name: UIKeyboardWillHideNotification,
object: nil)
}
func unregisterFromKeyboardNotifications () {
let center: NSNotificationCenter = NSNotificationCenter.defaultCenter()
center.removeObserver(self, name: UIKeyboardDidShowNotification, object: nil)
center.removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}
private func stopObservingKeyboardEvents() {
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillShowNotification, object: nil)
NSNotificationCenter.defaultCenter().removeObserver(self, name: UIKeyboardWillHideNotification, object: nil)
}
// Called when the UIKeyboardDidShowNotification is sent.
func keyboardWillBeShown(sender: NSNotification) {
let info: NSDictionary = sender.userInfo!
let value: NSValue = info.valueForKey(UIKeyboardFrameBeginUserInfoKey) as! NSValue
let keyboardSize: CGSize = value.CGRectValue().size
let contentInsets: UIEdgeInsets = UIEdgeInsetsMake(0.0, 0.0, keyboardSize.height, 0.0)
scrollview.contentInset = contentInsets
scrollview.scrollIndicatorInsets = contentInsets
// If active text field is hidden by keyboard, scroll it so it's visible
// Your app might not need or want this behavior.
var aRect: CGRect = self.view.frame
aRect.size.height -= keyboardSize.height + 80
let activeTextFieldRect: CGRect? = activeTextField?.frame
let activeTextFieldOrigin: CGPoint? = activeTextFieldRect?.origin
if (!CGRectContainsPoint(aRect, activeTextFieldOrigin!)) {
scrollview.scrollRectToVisible(activeTextFieldRect!, animated:true)
}
}
// Called when the UIKeyboardWillHideNotification is sent
func keyboardWillBeHidden(sender: NSNotification) {
let contentInsets: UIEdgeInsets = UIEdgeInsetsZero
scrollview.contentInset = contentInsets
scrollview.scrollIndicatorInsets = contentInsets
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.registerForKeyboardNotifications()
}
override func viewDidDisappear(animated: Bool) {
super.viewWillDisappear(animated)
NSNotificationCenter.defaultCenter().removeObserver(self)
}
// MARK: - Text Field
func textFieldDidBeginEditing(textField: UITextField) {
self.activeTextField = textField
}
func textFieldDidEndEditing(textField: UITextField) {
self.activeTextField = nil
}
}
Instead of doing this
var aRect: CGRect = self.view.frame
aRect.size.height -= keyboardSize.height + 80
do this
self.view.frame.y -= keyboardSize.height + 80
(not sure what the 80 is, but I'm keeping it there in case it is accounting for something on your app.)
the .height property will stretch your frame while the .y property will move it.