iOS-如何在点击UIView上的任意位置时从navigationItem.searchController中取消键盘?

时间:2018-08-27 08:15:39

标签: ios swift uisearchcontroller

我已经用新的SearchControllersearchBar实现了新的searchResultsController

这是我的实现方式:

resultViewController:

lazy var resultViewController: SearchResultViewController = {
    let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
    let searchResultViewController = storyboard.instantiateViewController(withIdentifier: "SearchResultViewController") as! SearchResultViewController
    searchResultViewController.delegate = self
    return searchResultViewController
}()

这是SearchController:

lazy var searchController: UISearchController = {
    let searchController = UISearchController(searchResultsController: resultViewController)
    searchController.searchBar.delegate = self
    searchController.obscuresBackgroundDuringPresentation = true
    searchController.searchResultsUpdater = self
    searchController.searchBar.placeholder = "Search.city.label".localizable()
    searchController.searchBar.tintColor = UIColor.white
    searchController.searchBar.barTintColor = UIColor.white
    UITextField.appearance(whenContainedInInstancesOf: [type(of: searchController.searchBar)]).tintColor = UIColor(red:0.00, green:0.47, blue:0.78, alpha:1.0)

    if let textfield = searchController.searchBar.value(forKey: "searchField") as? UITextField {
        if let backgroundview = textfield.subviews.first {

            // Background color
            backgroundview.backgroundColor = UIColor.white

            // Rounded corner
            backgroundview.layer.cornerRadius = 10;
            backgroundview.clipsToBounds = true;
        }
    }

    definesPresentationContext = true
    return searchController
}()

在我的viewWillAppear中,设置了navigationItem.searchController:

self.searchController.isActive = true

if #available(iOS 11.0, *) {
    self.navigationItem.searchController = searchController
    self.navigationItem.hidesSearchBarWhenScrolling = true
} else {
    // Fallback on earlier versions
}

我已经能够处理cancelButtonClicked了:

extension HomeViewController: UISearchBarDelegate {

    func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
        searchBar.endEditing(true)
        self.searchController.isActive = false
    }
}

此操作正在执行“取消”动画,在searchBar / searchController上隐藏键盘+非活动状态。两者同时点击1个取消按钮。

但是当用户在视图上的任意位置点击时,我将无法实现。

我尝试用轻击手势进行操作,但需要两次轻击才能实现相同的行为。

NB:

我的UIViewController中有一个UICollectionView,它占据了UIView中的所有位置。

这是我尝试过的:

override func viewDidLoad() {
    super.viewDidLoad()
    handleTapAnywhereToRemoveKeyboard()
}


func handleTapAnywhereToRemoveKeyboard() {
    let singleTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.singleTap(sender:)))
    //singleTapGestureRecognizer.numberOfTapsRequired = 1
    singleTapGestureRecognizer.cancelsTouchesInView = false
    self.view.addGestureRecognizer(singleTapGestureRecognizer)
}

@objc func singleTap(sender: UITapGestureRecognizer) {
    self.searchController.isActive = false
    self.searchController.searchBar.resignFirstResponder()
    self.searchController.searchBar.endEditing(true)
}

编辑:

我在想,也许是因为我的searchBar和searchController不在UIViewController的视图层次结构中,而更多在NavigationController中。

所以我也尝试了:

navigationController?.view.endEditing(true)

然后我在想,也许是因为UICollectionView中的UIScrollView抓住了水龙头。 因此,我尝试在UICollectionView而不是UIView上链接轻击手势,但没有成功。

4 个答案:

答案 0 :(得分:2)

请创建UIViewController来关闭键盘遍历应用程序。

extension UIViewController {
    func hideKeyboardWhenTappedAround() {
        let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
        tap.cancelsTouchesInView = false
        view.addGestureRecognizer(tap)
    }

    @objc func dismissKeyboard() {
        view.endEditing(true)
    }
}

按如下所示在UIViewController文件中使用上述代码。

override func viewDidLoad() {
     super.viewDidLoad()
     self.hideKeyboardWhenTappedAround() 
}

更新

您还可以使用以下代码从任何班级撤消键盘。

UIApplication.shared.sendAction(#selector(UIResponder.resign‌​FirstResponder), to: nil, from: nil, for: nil)

答案 1 :(得分:2)

如上所述,无需添加UITapGestureRecognizerUIViewContoller已经符合UIResponder接口(Objective C的传统),因此您可以像这样重写此方法:

extension UIViewController {

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
            self.view.window?.endEditing(true)
            super.touchesEnded(touches, with: event)
        }

}

答案 2 :(得分:0)

尝试Dimple Desai提供的解决方案,但将手势识别器添加到TableView或CollectionView或位于UIView顶部的对象。然后它应该起作用。

答案 3 :(得分:0)

override func viewDidLoad(){

   let tapView = UITapGestureRecognizer(target: self, action: #selector(self.hideKeyboard))
   self.view.addGestureRecognizer(tapView)
}

@objc func hideKeyboard(tap: UITapGestureRecognizer){

   self.view.endEditing(true)
}