iOS - Как убрать клавиатуру из контроллера navigationItem.search при нажатии в любом месте UIView? - PullRequest
0 голосов
/ 27 августа 2018

Я реализовал новый SearchController с searchBar и 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 я установил navigItem.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.Оба одновременно, с одним нажатием на кнопку отмены.

Но я не могу этого добиться, когда пользователь нажимает в любом месте на экране.

Я пытался с жестом касания, но это требует меня2 нажмите, чтобы добиться того же поведения.

NB:

Я получил UICollectionView в моем UIViewController, который занимает все место в 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 one.

Так что я также попытался с:

navigationController?.view.endEditing(true)

Я тогда подумал, может быть, это потому, что UIScrollView в моем UICollectionView ловит нажатие.Поэтому я попытался связать жест касания в UICollectionView вместо UIView, но безуспешно.

Ответы [ 4 ]

0 голосов
/ 11 сентября 2018

Нет необходимости добавлять UITapGestureRecognizer, как предложено выше.UIViewContoller уже соответствует UIResponder интерфейсу (унаследовано от Objective C), поэтому вы можете переопределить этот метод следующим образом:

extension UIViewController {

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

}
0 голосов
/ 27 августа 2018

Попробуйте решение от Dimple Desai, но добавьте распознаватель жестов в TableView или CollectionView или что-нибудь, что лежит поверх вашего UIView.Тогда это должно работать.

0 голосов
/ 10 сентября 2018
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)
}
0 голосов
/ 27 августа 2018

Пожалуйста, создайте 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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...