I have a textfield inside tableviewcontroller which is inside tabbarcontroller when i drag the keyboard down it lags right before dismiss. I am using the interactive mode so keyboard dismisses on drag.
class TempTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
tableView.keyboardDismissMode = .interactive
self.clearsSelectionOnViewWillAppear = false
tableView.register(TitleTableViewCell.self, forCellReuseIdentifier: "reuseIdentifier")
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath) as! TitleTableViewCell
return cell
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
}
my tableviewcell has a uitextfield. however when i drag the keyboard down it lags before being dismissed
class TitleTableViewCell: UITableViewCell {
let titleView: UITextField = {
let textView = UITextField()
textView.text = "Add your title ... "
textView.font = UIFont.preferredFont(forTextStyle: .body)
// textView.sizeToFit()
// textView.isScrollEnabled = false
textView.translatesAutoresizingMaskIntoConstraints=false
return textView
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.contentView.addSubview(titleView)
setTitleViewConstraints()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
func setTitleViewConstraints(){
titleView.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor,constant: 10).isActive=true
titleView.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor,constant: -10).isActive=true
titleView.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 10).isActive=true
titleView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor,constant: -10).isActive=true
}
}
class tabBarViewController: UITabBarController, UITabBarControllerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let homeViewController = HomeViewController()
homeViewController.tabBarItem = UITabBarItem(title: nil, image: UIImage(named: "home-tab")?.withRenderingMode(.alwaysOriginal), selectedImage: nil)
let discoverViewController = DiscoverViewController()
discoverViewController.tabBarItem = UITabBarItem(title: nil, image: UIImage(named: "discover-tab")?.withRenderingMode(.alwaysOriginal), selectedImage: nil)
let notificationViewController = NotificationViewController()
notificationViewController.tabBarItem = UITabBarItem(title: nil, image: UIImage(named: "notification-tab")?.withRenderingMode(.alwaysOriginal), selectedImage: nil)
let tempViewController = TempTableViewController()
tempViewController.tabBarItem = UITabBarItem(title: nil, image: UIImage(named: "profile-tab")?.withRenderingMode(.alwaysOriginal), selectedImage: nil)
let tabBarList = [homeViewController, discoverViewController,notificationViewController,tempViewController ]
self.viewControllers = tabBarList.map { viewController in
return UINavigationController(rootViewController: viewController)
}
}
}
this is the appdelegate class where tabbarcontroller is selected based on user credentials
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
var handle: AuthStateDidChangeListenerHandle?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
FirebaseApp.configure()
UINavigationBar.appearance().isOpaque = false
UINavigationBar.appearance().backgroundColor = .white
window = UIWindow(frame: UIScreen.main.bounds)
checkUserStatus()
return true
}
func checkUserStatus(){
window?.backgroundColor = UIColor.white
self.setupRootViewController(viewController: UIViewController())
handle = Auth.auth().addStateDidChangeListener {[weak self] auth,user in
if(user != nil){
self?.setupRootViewController(viewController: tabBarViewController())
}else{
self?.setupRootViewController(viewController: UINavigationController(rootViewController: WelcomeViewController()))
}
}
}
private func setupRootViewController(viewController: UIViewController) {
self.window!.rootViewController = viewController
self.window!.makeKeyAndVisible()
}
I launched your application with iOS 12 and it works correctly.
This solution may help you with iOS 13.
1) Add the observer in viewDidLoad()
override func viewDidLoad() {
...
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
2) Add function getKeyboardWindow()
private func getKeyboardWindow() -> UIWindow? {
for window in UIApplication.shared.windows {
if (NSStringFromClass(type(of: window).self) == "UIRemoteKeyboardWindow") {
return window
}
}
return nil
}
3) Add function keyboardWillHide(notification:)
@objc private func keyboardWillHide(notification: Notification) {
guard let keyboardWindow: UIWindow = getKeyboardWindow() else { return }
let screenWidth: CGFloat = UIScreen.main.bounds.width
let screenHeight: CGFloat = UIScreen.main.bounds.height
keyboardWindow.frame = CGRect(x: 0, y: 50, width: screenWidth, height: screenHeight)
}
P.S. However, I don't like to fix issues this way.
But in this case, I don't know a more elegant solution.