I have tried most of the examples here on StackOverflow. I also used Apple\'s. The problem I seem to have with them is that they don\'t account for the UITextField being in
Scroll UITextField above Keyboard in a UITableViewCell on a regular UIViewController swift 3 and Xcode 8.1
1) set Delegate = UITextFieldDelegate
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector: #selector(DayViewController.keyboardWillShow), name:NSNotification.Name.UIKeyboardWillShow, object: nil);
NotificationCenter.default.addObserver(self, selector: #selector(DayViewController.keyboardWillHide), name:NSNotification.Name.UIKeyboardWillHide, object: nil);
}
func textFieldDidBeginEditing(_ textField: UITextField) {
self.activeField = textField
}
func textFieldDidEndEditing(_ textField: UITextField) {
self.activeField = nil
}
//MARK: - Keyboard Show and Hide Methods
func keyboardWillShow(notification: NSNotification)
{
let info = notification.userInfo! as! [String: AnyObject],
kbSize = (info[UIKeyboardFrameBeginUserInfoKey] as! NSValue).cgRectValue.size,
contentInsets = UIEdgeInsets(top: 0, left: 0, bottom: kbSize.height, right: 0)
self.FourthTblMainTableView.contentInset = contentInsets
self.FourthTblMainTableView.scrollIndicatorInsets = contentInsets
var aRect = self.FourthTblMainTableView.frame
aRect.size.height -= kbSize.height
}
func keyboardWillHide(notification: NSNotification)
{
let contentInsets = UIEdgeInsets.zero
self.FourthTblMainTableView.contentInset = contentInsets
self.FourthTblMainTableView.scrollIndicatorInsets = contentInsets
}
This answer is for Xamarin iOS users, however someone can easily modify it to make it work with Swift or Objective C.
The solution is very simple and has worked perfectly in my case where I needed a cell to appear on the top half of the screen in order for the cell's textfield to be above keyboard. So what I did is the following:
I implemented textField.ShouldBeginEditing the following way:
myTextField.ShouldBeginEditing = textField =>
{
myTableView.ScrollToRow(indexPath, UITableViewScrollPosition.Top, true);
return true;
};
Where:
myTextField is the cell's text field,
myTableView is the table view,
indexPath is the cell's index path within the table view.
As I previously mentioned, this solution works perfectly in my case so I thought I could share it with you guys in case it works for you as well. Happy coding :)
In swift4 we can create an extension of UIViewController.
extension UIViewController {
//MARK: Keyboard user interactions
func handleContainerViewFrameOnKeyboardShowHide(originalContainerFrame: CGRect) {
NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillShow, object: nil, queue: OperationQueue.main) {(notification) in
var info = (notification as NSNotification).userInfo!
let keyboardFrame: CGRect = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
var tableViewFrame = originalContainerFrame
tableViewFrame.size.height = originalContainerFrame.size.height - keyboardFrame.size.height
self.view.frame = tableViewFrame
}
NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillHide, object: nil, queue: OperationQueue.main) { (notification) in
self.view.frame = originalContainerFrame
}
}
}
My solution (worked on Xcode 8.3.3, Swift 3, iOS 10.3.1):
class MyTableViewController: UITableViewController {
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector: #selector(actionKeyboardDidShow(with:)), name: .UIKeyboardDidShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(actionKeyboardWillHide(with:)), name: .UIKeyboardWillHide, object: nil)
}
override func viewDidDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self, name: .UIKeyboardDidShow, object: nil)
NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillHide, object: nil)
}
@objc private func actionKeyboardDidShow(with notification: Notification) {
guard let userInfo = notification.userInfo as? [String: AnyObject],
let keyboardFrame = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue
else { return }
var contentInset = self.tableView.contentInset
contentInset.bottom += keyboardFrame.height
self.tableView.contentInset = contentInset
self.tableView.scrollIndicatorInsets = contentInset
}
@objc private func actionKeyboardWillHide(with notification: Notification) {
guard let userInfo = notification.userInfo as? [String: AnyObject],
let keyboardFrame = (userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue
else { return }
var contentInset = self.tableView.contentInset
contentInset.bottom -= keyboardFrame.height
self.tableView.contentInset = contentInset
self.tableView.scrollIndicatorInsets = contentInset
}
}