键盘在交互式表视图上消失非常有缺陷。

6

我有一个文本字段在表视图控制器中,该表视图控制器位于选项卡控制器内。当我将键盘向下拖动时,它会在关闭之前出现延迟。我正在使用交互模式,因此可以通过拖动来关闭键盘。

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类,根据用户凭证选择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()
    }

enter image description here


只是一个更新。即使我删除了tabbarcontroller,只加载具有textfield的tempViewController,这种情况仍然发生。非常奇怪。 - j.doe
也发生在模拟器上。我尝试创建一个新项目,但仍然发生。 - j.doe
你能否尝试使用.onDrag而不是.interactive? - Radhe Yadav
你所说的“buggy keyboard”是什么意思?屏幕底部会出现键盘建议,但只会显示一秒钟就消失了...你是指那个吗? - Gokul G
看起来这个 bug 来自于 iOS 13 中的 tableView.keyboardDismissMode。当在 scrollViewDidScroll 中使用像 view.endEditing(true) 这样的正常方式时,键盘消失更加平滑。此 bug 在 iOS 12.2 及之前版本中不会发生。 - Trai Nguyen
显示剩余3条评论
4个回答

7

我使用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)
}

顺便说一下,我不喜欢用这种方法来解决问题。

但在这种情况下,我不知道有更优雅的解决方案。

在此输入图片描述


2

doe,

你所做的是正确的,我并不认为这会成为问题,因为联系人应用程序也具有与你的相同功能(即表格视图中的文本字段)。联系人应用程序的行为也是一样的。

请查看联系人应用程序和你的应用程序的比较屏幕录像:

Contacts App . Your App

如果你仍然想要修复它,我建议删除自动更正,如果你的要求允许的话。

textView.autocorrectionType = .no

0

你可以尝试设置一个空视图 textView.inputAccessoryView = UIView()


0
由于表视图继承了滚动视图,您可以重写一个滚动视图方法“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()
            }
        }

那是我目前正在使用的解决方案。然而,由于您无法使用键盘滚动,因此其效果与.interactive或.drag不同。当使用.interactive或.drag时,只有在向下滑动时才应该关闭键盘。 - j.doe
也许你可以尝试使用NotificationCenter来处理视图,这是我的代码片段;https://gist.github.com/erdemildiz/7aeb71709651cec96d8dc3dffc766518 @j.doe - eildiz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接