UISearchBar resignFirstResponder无法正常工作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UISearchBar resignFirstResponder无法正常工作相关的知识,希望对你有一定的参考价值。

UIViewController需要隐藏viewWillDisappearviewDidDisappear方法中的键盘。 UIViewController消失后留在记忆中,可以再次出现。在第一次出现时,UISearchBar不是firstResponder而且键盘是隐藏的。但是,如果我弹出显示键盘的UIViewController然后再推它 - 键盘没有隐藏,但我打电话:

override func viewDidLoad() {
    super.viewDidLoad()
    instrumentsTableView.register(UINib(nibName: kDealsFilterInstrumentTableViewCellNib, bundle: nil), forCellReuseIdentifier: kDealsFilterInstrumentTableViewCellReusableId)
    instrumentsTableView.dataSource = self
    instrumentsTableView.delegate = self
}

override func viewDidDisappear(_ animated: Bool) {
    super.viewDidDisappear(animated)
    if presenter.numberOfInstruments != 0 {
        instrumentsTableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: false)
    }
    KeyboardManager.shared.unsubscribe()
    instrumentsSearchBar.text = ""
    presenter.findInstruments(with: "") //just sets settings to default/ reloads data


    instrumentsSearchBar.endEditing(true)
    instrumentsSearchBar.resignFirstResponder()
    view.endEditing(true)
    view.resignFirstResponder()
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    KeyboardManager.shared.subscribe(self)
}

KeyboardManager - 如果键盘状态已更改,则发送通知(如果相关):

final class KeyboardManager {

    private init() {
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(_:)), name: Notification.Name.UIKeyboardWillShow, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide(_:)), name: Notification.Name.UIKeyboardWillHide, object: nil)
    }

    static let shared = KeyboardManager()

    @objc private func keyboardWillShow(_ notification: Notification) {
        if let keyboardSize = notification.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue {
            let height = keyboardSize.cgRectValue.height
            keyboardHeight = height
            keyboardState = .shown
        }
    }

    @objc private func keyboardWillHide(_ notification: Notification) {
        keyboardHeight = 0
        keyboardState = .hidden
    }

    private weak var subscriber: KeyboardManagerDelegate?

    func subscribe(_ delegate: KeyboardManagerDelegate) {
        subscriber = delegate
    }

    func unsubscribe() {
        subscriber = nil
    }

    private var keyboardHeight: CGFloat = 0

    private var keyboardState: KeyboardState = .hidden {
        didSet {
            if keyboardState != oldValue {
                subscriber?.keyboardDidChange(state: keyboardState, height: keyboardHeight)
            }
        }
    }
}

enum KeyboardState {
    case shown
    case hidden
}

protocol KeyboardManagerDelegate: class {
    func keyboardDidChange(state: KeyboardState, height: CGFloat)
}

我试图在viewWillAppearviewWillDisappear中使用这个代码 - 但UISearchBar仍然是firstResponder。如果我弹出键盘被隐藏 - 它会保持隐藏状态。可能是什么问题?

截屏:

enter image description here

Sample project with the same issue on bitbucket

答案

对于键盘问题,这将工作正常,

self.view.endEditing(true)

viewWillDisappearviewDidDisappear中写这个

另一答案

我已经尝试过你的代码:Sample project with the same issue on bitbucket和它按预期工作并且很好。

这是代码。

class ViewController: UIViewController {

    @IBAction func btnShowSearch(button: UIButton) {
        if let search = self.storyboard?.instantiateViewController(withIdentifier: "SeachBarViewController") {
            self.navigationController?.pushViewController(search, animated: true)
        }
    }

}

// SeachBarViewController
class SeachBarViewController: UIViewController {

    @IBOutlet var searchBar: UISearchBar!

    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        attemptToHidKeyboard()
    }

    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        attemptToHidKeyboard()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        attemptToHidKeyboard()
    }

    override func didMove(toParentViewController parent: UIViewController?) {
        if parent == nil {
            attemptToHidKeyboard()
        }
    }

    override func willMove(toParentViewController parent: UIViewController?) {
        if parent == nil {
            attemptToHidKeyboard()
        }
    }


    private func attemptToHidKeyboard() {
        self.searchBar.resignFirstResponder()
        self.searchBar.endEditing(true)
        self.view.resignFirstResponder()
        self.view.endEditing(true)
    }
}

结果如下:

enter image description here

以上是关于UISearchBar resignFirstResponder无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

UISearchBar becomeFirstResponder 返回 0,但对 UISearchBar 有有效引用

搜索栏UISearchBar的使用

UISearchBar

直接调用 UIResponder.resignFirstResponder 可以吗?

iOS学习—— UISearchBar的使用

UISearchBar 和 resignFirstResponder