键盘在 tableview interactive 上关闭非常有问题
Keyboard dismiss very buggy on tableview interactive
我在 tableviewcontroller 内有一个文本字段,当我向下拖动键盘时它在 tabbarcontroller 内,它在关闭之前滞后。我正在使用交互模式,因此键盘在拖动时会消失。
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
}
}
我的 tableviewcell 有一个 uitextfield。然而,当我向下拖动键盘时,它在被解雇之前会滞后
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)
}
}
}
这是 appdelegate class,其中根据用户凭据选择了 tabbarcontroller
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()
}
因为 tableviews 继承自 ScrollViews,所以您可以覆盖 scrollview 方法 "scrollViewWillEndDragging" 并调用 endEditing(true)
override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
self.view.endEditing(true)
}
你甚至可以做得更多
您可以使用函数签名的速度参数检测用户何时向上或向下滚动,如下所示:
向上
override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
if(velocity.y > 0){
self.view.endEditing(true)
self.view.layoutIfNeeded()
}
}
向下
override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
if(velocity.y < 0){
self.view.endEditing(true)
self.view.layoutIfNeeded()
}
}
母鹿,
你做的是对的,我不认为这是一个问题,甚至联系人应用程序也有与你的相同的功能(即 [=24= 中的文本字段) ] 看法)。联系人应用程序也以同样的方式运行
找到联系人app和你的对比录屏,
.
如果您仍然想修复它,我建议您删除自动更正,如果您的要求允许的话。
textView.autocorrectionType = .no
我用 iOS 12 启动了你的应用程序,它工作正常。
此解决方案可能会帮助您 iOS 13.
1) 在viewDidLoad()
中添加观察者
override func viewDidLoad() {
...
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
2) 添加函数getKeyboardWindow()
private func getKeyboardWindow() -> UIWindow? {
for window in UIApplication.shared.windows {
if (NSStringFromClass(type(of: window).self) == "UIRemoteKeyboardWindow") {
return window
}
}
return nil
}
3) 添加函数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。但是,我不喜欢这样解决问题。
但在这种情况下,我不知道更优雅的解决方案。
您可以尝试设置空视图textView.inputAccessoryView = UIView()
我在 tableviewcontroller 内有一个文本字段,当我向下拖动键盘时它在 tabbarcontroller 内,它在关闭之前滞后。我正在使用交互模式,因此键盘在拖动时会消失。
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
}
}
我的 tableviewcell 有一个 uitextfield。然而,当我向下拖动键盘时,它在被解雇之前会滞后
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)
}
}
}
这是 appdelegate class,其中根据用户凭据选择了 tabbarcontroller
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()
}
因为 tableviews 继承自 ScrollViews,所以您可以覆盖 scrollview 方法 "scrollViewWillEndDragging" 并调用 endEditing(true)
override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
self.view.endEditing(true)
}
你甚至可以做得更多 您可以使用函数签名的速度参数检测用户何时向上或向下滚动,如下所示:
向上
override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
if(velocity.y > 0){
self.view.endEditing(true)
self.view.layoutIfNeeded()
}
}
向下
override func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
if(velocity.y < 0){
self.view.endEditing(true)
self.view.layoutIfNeeded()
}
}
母鹿,
你做的是对的,我不认为这是一个问题,甚至联系人应用程序也有与你的相同的功能(即 [=24= 中的文本字段) ] 看法)。联系人应用程序也以同样的方式运行
找到联系人app和你的对比录屏,
如果您仍然想修复它,我建议您删除自动更正,如果您的要求允许的话。
textView.autocorrectionType = .no
我用 iOS 12 启动了你的应用程序,它工作正常。
此解决方案可能会帮助您 iOS 13.
1) 在viewDidLoad()
override func viewDidLoad() {
...
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
2) 添加函数getKeyboardWindow()
private func getKeyboardWindow() -> UIWindow? {
for window in UIApplication.shared.windows {
if (NSStringFromClass(type(of: window).self) == "UIRemoteKeyboardWindow") {
return window
}
}
return nil
}
3) 添加函数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。但是,我不喜欢这样解决问题。
但在这种情况下,我不知道更优雅的解决方案。
您可以尝试设置空视图textView.inputAccessoryView = UIView()