tipotto
tipotto

Reputation: 107

【UISearchController / UISearchBar】How to add tap gesture to search icon?

I am currently using UISearchController in my app.

I'd like to execute a process(NOT search process) using text entered in textField when leftView's search icon is tapped.

Therefore, I attempted to add tap gesture(or long press gesture) to the icon using UIGestureRecognizer and UILongPressGestureRecognizer, and it didn't make anything happen.

Question 1:
Does the icon originally not trigger any actions when tapped? (It doesn't even call "searchBarSearchButtonClicked" function when tapped.)

Question 2:
Is there any way to use the icon like clickable button, and trigger a specific action when tapped?

For your reference, my code and screen image are below.
If you have some additional information you need, please let me know.
Thank you in advance.

Update: Bookmark button didn't work as expected...
I attempted for bookmark button. However, it didn't work as expected because it was hidden underneath a clear icon when entering text.
It would be ideal if bookmark button keeps being shown even though text is entered.

target icon image

target icon image

Properties:

let searchController = UISearchController(searchResultsController: nil)
var keyword = ""

setupSearchController:
I changed the color and image of search icon in the function below.

private func setupSearchController() {
    navigationItem.searchController = searchController
    navigationItem.hidesSearchBarWhenScrolling = true
    definesPresentationContext = true

    searchController.delegate = self
    searchController.obscuresBackgroundDuringPresentation = false
    searchController.searchResultsUpdater = self

    searchController.searchBar.delegate = self
    searchController.searchBar.placeholder = "Search channels"

    // search icon settings
    searchController.searchBar.searchTextField.leftView?.tintColor = .link
    searchController.searchBar.setImage(UIImage(systemName: "globe"), for: .search, state: .normal)
}

setupTranslateButton:
I attempted for two ways, UITapGestureRecognizer and UILongPressGestureRecognizer, both of which didn't make anything happen.

// UITapGestureRecognizer version
private func setupTranslateButton() {
    let transButton = searchController.searchBar.searchTextField.leftView!

    let tap = UITapGestureRecognizer(target: self, action: #selector(translateKeyword))
        transButton.addGestureRecognizer(tap)
    searchController.searchBar.searchTextField.addSubview(transButton)
}

// UILongPressGestureRecognizer version
private func setupTranslateButton() {
    let transButton = searchController.searchBar.searchTextField.leftView!

    let tap = UILongPressGestureRecognizer(target: self, action: #selector(translateKeyword))
    tap.minimumPressDuration = 0
    transButton.addGestureRecognizer(tap)
} 

translateKeyword:
I'd like the following function called when tap gesture is successfully triggered.

@objc func translateKeyword(_ sender: UILongPressGestureRecognizer) {

    print("Translate button is clicked...")

    // keyword string should exist by the process executed in "updateSearchResults" function 
    if keyword.isEmpty {
        print("Keyword is empty")
        return
    }

    // The following process is here...
}

updateSearchResults:
All texts are put into keyword variable every time it's entered in textField.

func updateSearchResults(for searchController: UISearchController) {
        
    print("updateSearchResults")
       
    guard let inputKeyword = searchController.searchBar.text, !inputKeyword.isEmpty else {
        print("Keyword is not entered...")
        return
    }
        
    keyword = inputKeyword
}

Upvotes: 3

Views: 781

Answers (1)

Abiola Akinnubi
Abiola Akinnubi

Reputation: 313

So to solve your challenge, I have found two thing I think you need to do as I have tested and it works here.

1.

 private func setupTranslateButton() {
        let transButton = searchController.searchBar.searchTextField.leftView!

        let tap = UITapGestureRecognizer(target: self, action: #selector(translateKeyword))
        //Add this line of user interaction Enabled to be true;
        transButton.isUserInteractionEnabled = true;
        searchController.searchBar.setImage(UIImage(systemName: "globe"), for: .search, state: .normal)
            transButton.addGestureRecognizer(tap)
        searchController.searchBar.searchTextField.addSubview(transButton)
    }
  1. Call it in the function below

        private func setupSearchController() {
         navigationItem.searchController = searchController
         navigationItem.hidesSearchBarWhenScrolling = true
         definesPresentationContext = true
         searchController.delegate = self
         searchController.obscuresBackgroundDuringPresentation = false
         searchController.searchResultsUpdater = self
    
         searchController.searchBar.delegate = self
         searchController.searchBar.placeholder = "Search channels"
    
         // search icon settings
         searchController.searchBar.searchTextField.leftView?.tintColor = .link
         // calling it here
         setupTranslateButton()
     }
    
  2. In viewDidLoad call this item below.

    setupSearchController()

Mind you this is with the assumption that you have implemented all the necessary protocols and delegates of the SearchbarController class. this fixes your challenge.

Upvotes: 2

Related Questions