【问题标题】:UISearchBar resignFirstResponder not workingUISearchBar resignFirstResponder 不工作
【发布时间】:2018-03-02 10:23:22
【问题描述】:

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。如果我在隐藏键盘的情况下弹出 - 它会保持隐藏状态。可能是什么问题?

截图:

Sample project with the same issue on bitbucket

【问题讨论】:

  • 你能分享GIF吗
  • 你在使用 UISearchController 吗?然后只需在viewWillDisappear 中调用searchController.isActive = false,它就会关闭搜索栏。
  • @fl034 不,我正在使用 UIViewControllerUISearchBar
  • 在弹出 viewController 之前尝试退出搜索栏。
  • @JuicyFruit 你在 viewWillAppear 中写了 searchBar.becomeFirstResponder() 吗??

标签: ios swift uiviewcontroller uisearchbar


【解决方案1】:

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

self.view.endEditing(true)

写在viewWillDisappearviewDidDisappear

【讨论】:

    【解决方案2】:

    我已经尝试过您的代码: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)
        }
    }
    

    结果如下:

    【讨论】:

    • 你能指定iOS版本的模拟器吗?你没有更改任何代码?
    • 你没有改变rootviewcontroller的代码,我用SearchBar存储控制器?如果是这样,它必须已经修复,因为它在使用 Xcode 9.2 构建的 iOS 11.2 和 iOS 10 上的行为不是这样
    • 我使用了你的故事板和 SearchBarController 文件。没有别的......它的工作原理。我也有 Xcode 9.2。让我检查一下 Xcode 9.2
    • 你的代码不一样。检查我的RootViewController,我想存储SearchViewController,而不是在按钮单击时启动它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多