【问题标题】:Keyboard dismiss very buggy on tableview interactive键盘在 tableview 交互上关闭非常错误
【发布时间】:2020-04-04 07:21:30
【问题描述】:

我在 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)

        }
    }

}

这是根据用户凭据选择 tabbarcontroller 的 appdelegate 类

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()
    }

【问题讨论】:

  • 只是一个更新。即使我删除 tabbarcontroller 并仅加载具有文本字段的 tempViewController 也会发生这种情况。很奇怪
  • 也在模拟器上发生。我尝试制作一个新项目,但它仍然会发生
  • 你不能尝试 .onDrag 而不是 .interactive
  • 如果你能在github上分享你的项目我会看看
  • .onDrag 给出了同样的错误。 git 是github.com/ahmed14642/keyboardBug。非常感谢您的帮助

标签: ios swift uitableview lag uikeyboard


【解决方案1】:

我使用 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】:

    确实,

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

    找到联系人应用和你的对比录屏,

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

    textView.autocorrectionType = .no
    

    【讨论】:

      【解决方案3】:

      由于 tableviews 继承自 ScrollViews,您可以覆盖滚动视图方法“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 一样向下滑动时才应关闭键盘
      • 也许你可以试试 NotificationCenter 来查看,这是我的要点; gist.github.com/erdemildiz/7aeb71709651cec96d8dc3dffc766518@j.doe
      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-09-09
        • 2015-06-17
        • 2020-04-18
        • 2016-01-26
        • 2010-12-06
        • 1970-01-01
        • 2012-03-16
        相关资源
        最近更新 更多