How to manage keyboard when there are UITextFields in UITableView using swift?
How to manage keyboard when there are UITextFields in UITableView using swift?
I am trying to find a way to avoid keyboard to not block selected UITextField in dynamic UITableViews.
I am aware this is a common issue and there are a lot of answers to this. However, answers I found are either in Obj-C or not involving dynamic UITableView.
My table view being has its own UITableViewCell so UITextFields are connected to it.
Also, I want to refresh the cell when UITextField entry has been made. I can pass that info (I am guessing cell's IndexPath.row?) to the UIViewController and have it listen to change and apply reload cell method?
Here is the related code I have:
class favCell: UITableViewCell, UITextFieldDelegate
@IBOutlet weak var deciPadField: UITextField!
@objc func doneClicked()
updateTotalWorth()
deciPadField.resignFirstResponder()
deciPadField.endEditing(true)
func textFieldDidBeginEditing(_ textField: UITextField)
deciPadField.becomeFirstResponder()
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool
let currentString: NSString = (textField.text ?? "") as NSString
let newString = currentString.replacingCharacters(in: range, with: string)
return newString.count <= 10
func textFieldShouldReturn(_ textField: UITextField) -> Bool
updateTotalWorth()
deciPadField.resignFirstResponder()
return true
private func textViewDidEndEditing(_ textView: UITextView)
updateTotalWorth()
deciPadField.endEditing(true)
UPDATE:
If I can access my ViewControllers view from UITableViewCell, below code will do the trick:
func animateTextField(textField: UITextField, up: Bool)
let movementDistance:CGFloat = -130
let movementDuration: Double = 0.3
var movement:CGFloat = 0
if up
movement = movementDistance
else
movement = -movementDistance
UIView.beginAnimations("animateTextField", context: nil)
UIView.setAnimationBeginsFromCurrentState(true)
UIView.setAnimationDuration(movementDuration)
// Below line giving error, could not find the view. My ListVC.view should be referred to.
self.view.frame = self.view.frame.offsetBy(dx: 0, dy: movement)
UIView.commitAnimations()
func textFieldDidBeginEditing(textField: UITextField)
self.animateTextField(textField: textField, up:true)
func textFieldDidEndEditing(textField: UITextField)
self.animateTextField(textField: textField, up:false)
Thank you!
If you (A) subclass
UITableViewController, it should be handled automatically for you. If you (B) are adding a UITableView as a subview of a UIViewController, you'll have to make the adjustments yourself when keyboard is shown / hidden. Are you doing (A) or (B)?– DonMag
Nov 9 '17 at 13:12
UITableViewController
UITableView
UIViewController
I am doing B. I was aware of UITableViewController variance.
– sc13
Nov 9 '17 at 13:18
OK - then you have to handle it yourself. There are really so many examples out there already... read through this post and see if you can get it working. If not, come back and post the code you are trying to use: stackoverflow.com/questions/1126726/…
– DonMag
Nov 9 '17 at 16:25
1 Answer
1
Well I finally figured out how to solve this. I implemented this answer: https://stackoverflow.com/a/41040630/4441676
Here is the solved code:
Inside ViewController's ViewDidLoad added two observers as below:
// Notification Observers
NotificationCenter.default.addObserver(self, selector: #selector(ListVC.keyboardWillShow(notification:)), name: Notification.Name.UIKeyboardDidShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ListVC.keyboardWillHide(notification:)), name: Notification.Name.UIKeyboardDidHide, object: nil)
And added related two functions:
@objc func keyboardWillShow(notification: Notification)
if let keyboardHeight = (notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height
tableView.contentInset = UIEdgeInsetsMake(0, 0, keyboardHeight, 0)
@objc func keyboardWillHide(notification: Notification)
UIView.animate(withDuration: 0.2, animations:
// For some reason adding inset in keyboardWillShow is animated by itself but removing is not, that's why we have to use animateWithDuration here
self.tableView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0)
)
In the UITableViewCell where UITextFields are connected, simply implement UITextField Delegate and add related Notification.posts when keyboard will show/hide:
deciPadField.delegate = self
func textFieldDidBeginEditing(_ textField: UITextField)
NotificationCenter.default.post(name: Notification.Name.UIKeyboardDidShow, object: self)
func textFieldDidEndEditing(_ textField: UITextField)
NotificationCenter.default.post(name: Notification.Name.UIKeyboardDidHide, object: self)
I have inputAccessoryView, so dismissing keyboard handled via following:
// Decipad config for adding Done button above itself
let toolBar = UIToolbar()
toolBar.sizeToFit()
let flexiableSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.flexibleSpace, target: nil, action: nil)
let doneButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.done, target: self, action: #selector(self.doneClicked))
toolBar.setItems([flexiableSpace, doneButton], animated: false)
@objc func doneClicked()
updateTotalWorth()
deciPadField.resignFirstResponder()
deciPadField.endEditing(true)
Hope this would help for someone else.
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
try self.view.endediting()
– Sagar Bhut
Nov 9 '17 at 12:51