UISearchbar clearButton forces the keyboard to appear

后端 未结 12 1915
暖寄归人
暖寄归人 2020-11-30 20:40

I have a UISearchBar which acts as a live filter for a table view. When the keyboard is dismissed via endEditing:, the query text and the gray circular \"clear\" button rem

相关标签:
12条回答
  • 2020-11-30 21:22

    I found a pretty safe way to know if the clear button has been pressed, and ignore the times when the user just delete the last character of the UISearchBar. Here it is :

    - (BOOL)searchBar:(UISearchBar *)searchBar shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
    {
        _isRemovingTextWithBackspace = ([searchBar.text stringByReplacingCharactersInRange:range withString:text].length == 0);
    
        return YES;
    }
    
    - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
    {
        if (searchText.length == 0 && !_isRemovingTextWithBackspace)
        {
            NSLog(@"Has clicked on clear !");
        }
    }
    

    Pretty simple and straightforward, isn't it :) ? The only thing to note is that if the user clicks the clear button when editing the UISearchBar's UITextField, you will have two pings, whereas you'll get only one if the user clicks it when it is not being edited.


    Edit : I can't test it, but here's the swift version, as per Rotem :

    var isRemovingTextWithBackspace = false
    
    func searchBar(searchBar: UISearchBar, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool
    {
        self.isRemovingTextWithBackspace = (NSString(string: searchBar.text!).stringByReplacingCharactersInRange(range, withString: text).characters.count == 0)
        return true
    }
    
    func searchBar(searchBar: UISearchBar, textDidChange searchText: String)
    {
        if searchText.characters.count == 0 && !isRemovingTextWithBackspace
        { 
            NSLog("Has clicked on clear !")
        }
    }
    

    @Rotem's update (Swift2):

    var isRemovingTextWithBackspace = false
    
    func searchBar(searchBar: UISearchBar, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool {
        self.isRemovingTextWithBackspace = (NSString(string: searchBar.text!).stringByReplacingCharactersInRange(range, withString: text).characters.count == 0)
        return true
    }
    
    func searchBar(searchBar: UISearchBar, textDidChange searchText: String) {
        if searchText.characters.count == 0 && !isRemovingTextWithBackspace {
            NSLog("Has clicked on clear!")
        }
    }
    
    0 讨论(0)
  • 2020-11-30 21:27

    Pressing the "clear" button in a UISearchBar automatically opens the keyboard even if you call searchBar.resignFirstResponder() within the textDidChange UISearchBarDelegate method.

    To actually hide the keyboard when you press the "x" to clear the UISearchBar, use the following code. This way, even if textDidChange gets called while typing something in the UISearchBar, you only hide the keyboard if you delete all the text within it, weather you use the delete button or you click the "x":

    extension ViewController: UISearchBarDelegate {
        func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
            if searchBar.text!.count == 0 {
                DispatchQueue.main.async {
                    searchBar.resignFirstResponder()
                }
            } else {
                // Code to make a request here.
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-30 21:28

    In your endEditing method, why don't you clear the UISearchBar and there? Since that must be where you resign first responder also, it makes sense.

    0 讨论(0)
  • 2020-11-30 21:32

    A Swift version of @boliva 's answer.

    class MySearchContentController: UISearchBarDelegate {
    
        private var searchBarShouldBeginEditing = true
    
        func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
            searchBarShouldBeginEditing = searchBar.isFirstResponder
        }
    
        func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool {
            defer {
                searchBarShouldBeginEditing = true
            }
            return searchBarShouldBeginEditing
        }
    }
    
    0 讨论(0)
  • 2020-11-30 21:32

    I've run into this several times now. I really appreciate the answers that people have given.

    Ultimately, I would really like to see Apple just allow us (the developers) to detect when the clear button has been pressed.

    It is obvious that pressing it gets detected because any text in the search box gets cleared.

    I am guessing that it just isn't very high up on their list of priorities right now... But I really wish someone at Apple would give UISearchBar a little love!

    0 讨论(0)
  • 2020-11-30 21:34

    I've found that resignFirstResponder doesn't work when textDidChange is called from a touch to the "clear button". However, using performSelection: withObject: afterDelay: seems to be an effective workaround:

    - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
    {
        if ([searchText length] == 0) {
            [self performSelector:@selector(hideKeyboardWithSearchBar:) withObject:searchBar afterDelay:0];
        }
    }
    
    - (void)hideKeyboardWithSearchBar:(UISearchBar *)searchBar
    {   
        [searchBar resignFirstResponder];   
    }
    
    0 讨论(0)
提交回复
热议问题