UISearchbar clearButton强制键盘出现

Jen*_*ohl 44 iphone keyboard appearance uisearchbar uisearchbardelegate

我有一个UISearchBar,它充当表视图的实时过滤器.当键盘通过endEditing:解除时,查询文本和灰色圆形"清除"按钮保持不变.从这里,如果我点击灰色的"清除"按钮,键盘会在文本被清除时重新出现.

我该如何防止这种情况?如果键盘当前未打开,我希望该按钮在不重新打开键盘的情况下清除文本.

当我点击清除按钮时,会调用一个协议方法.但是向UISearchBar发送resignFirstResponder消息对键盘没有任何影响.

bol*_*iva 122

这是一个老问题,我遇到了同样的问题,并设法通过以下方式解决它:

searchBar:textDidChange:由于用户点击"清除"按钮而调用UISearchBarDelegate 的方法时,searchBar还没有成为第一个响应者,所以我们可以利用它来检测用户实际上何时打算清除搜索并不将焦点带到searchBar和/或做其他事情.

为了跟踪这一点,我们需要BOOL在viewController中声明一个ivar,它也是searchBar委托(让我们调用它shouldBeginEditing)并使用初始值设置它YES(假设我们的viewController类叫做SearchViewController):

@interface SearchViewController : UIViewController <UISearchBarDelegate> {
    // all of our ivar declarations go here...
    BOOL shouldBeginEditing;
    ....
}

...
@end



@implementation SearchViewController
...
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
        ...
        shouldBeginEditing = YES;
    }
}
...
@end
Run Code Online (Sandbox Code Playgroud)

稍后,在UISearchBarDelegate中,我们实现了searchBar:textDidChange:searchBarShouldBeginEditing:方法:

- (void)searchBar:(UISearchBar *)bar textDidChange:(NSString *)searchText {
    NSLog(@"searchBar:textDidChange: isFirstResponder: %i", [self.searchBar isFirstResponder]);
    if(![searchBar isFirstResponder]) {
        // user tapped the 'clear' button
        shouldBeginEditing = NO;
        // do whatever I want to happen when the user clears the search...
    }
}


- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)bar {
    // reset the shouldBeginEditing BOOL ivar to YES, but first take its value and use it to return it from the method call
    BOOL boolToReturn = shouldBeginEditing;
    shouldBeginEditing = YES;
    return boolToReturn;
}
Run Code Online (Sandbox Code Playgroud)

基本上就是这样.

最好


Gre*_*aun 33

我发现当从触摸到"清除按钮"调用textDidChange时,resignFirstResponder不起作用.但是,使用performSelection: withObject: afterDelay:似乎是一种有效的解决方法:

- (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];   
}
Run Code Online (Sandbox Code Playgroud)


Cyb*_*ndy 10

我找到了一种非常安全的方法来知道是否按下了清除按钮,并忽略了用户刚刚删除UISearchBar的最后一个字符的时间.这里是 :

- (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 !");
    }
}
Run Code Online (Sandbox Code Playgroud)

非常简单明了,不是吗:)?唯一需要注意的是,如果用户在编辑UISearchBar的UITextField时单击清除按钮,则会有两个ping,而如果用户在未编辑时单击它,则只能获得一个ping.


编辑:我无法测试它,但根据Rotem,这里是swift版本:

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 !")
    }
}
Run Code Online (Sandbox Code Playgroud)

@Rotem的更新(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!")
    }
}
Run Code Online (Sandbox Code Playgroud)


ben*_*ioT 8

我使用@ boliva的答案以及@ radiospiel 对不同SO问题的答案的组合:

@interface SearchViewController : UIViewController <UISearchBarDelegate> {
    // all of our ivar declarations go here...
    BOOL shouldBeginEditing;
    ....
}

...
@end

@implementation SearchViewController
...
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
        ...
        shouldBeginEditing = YES;
    }
}
...

- (void) searchBar:(UISearchBar *)theSearchBar textDidChange:(NSString *)searchText {
    // TODO - dynamically update the search results here, if we choose to do that.

    if (![searchBar isFirstResponder]) {
        // The user clicked the [X] button while the keyboard was hidden
        shouldBeginEditing = NO;
    }
    else if ([searchText length] == 0) {
        // The user clicked the [X] button or otherwise cleared the text.
        [theSearchBar performSelector: @selector(resignFirstResponder)
                        withObject: nil
                        afterDelay: 0.1];
    }
}

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)bar {
    // reset the shouldBeginEditing BOOL ivar to YES, but first take its value and use it to return it from the method call
    BOOL boolToReturn = shouldBeginEditing;
    shouldBeginEditing = YES;
    return boolToReturn;
}
@end
Run Code Online (Sandbox Code Playgroud)