UISearchBar键盘回车键

8
我正在使用UISearchBar来将文本输入与数据库中的条目匹配,并在用户键入时在UITableView中向用户显示匹配的结果。一切都很好,但是我找不到一种方法来更改搜索栏键盘的返回键类型。默认情况下,它将标准的“return”键替换为一个“Search”按钮。因为我正在用户键入时进行实时搜索,所以我不需要这个按钮,而且它的存在并且无法使用会导致一些可用性问题。
已尝试的解决方案:
1. 我可以使用setKeyboard:UIKeyboardType方法设置键盘,但这似乎不能覆盖替换返回键(在标准键盘上)为“Search”键的默认设置,并且它不允许更改此返回键的访问权限。
2. 我考虑使用UITextField,通过UITextInputTraits协议使我能够访问returnKeyType属性。然而,我的问题是我正在实现UISearchBarDelegate方法searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText,如果使用UITextField,我就会失去它。
是否有一种方法,我可以保留搜索栏代理方法的功能,同时合法地访问键盘的返回键?
事实上,我正在实现的几乎完全相同的屏幕在Apple的时钟应用程序中找到
屏幕截图:
所以任何关于清洁解决方案的帮助将不胜感激。请注意,右下角的返回键而不是默认的“Search”按钮。

https://dev59.com/5HE85IYBdhLWcg3wl0jF#35147293 - Zaraki
9个回答

20

我试过所有这些解决方案都没有成功,直到我意识到在IOS8中,你只需要设置searchBar.returnKey = .Done或任何你喜欢的UIReturnKeyType。叹气。


谢谢伙计,这个对我有用:searchBar.returnKeyType = .Done - Wilson

20

iOS 7中与@sudip的答案略有不同。

for (UIView *subview in self.searchBar.subviews)
{
    for (UIView *subSubview in subview.subviews)
    {
        if ([subSubview conformsToProtocol:@protocol(UITextInputTraits)])
        {
            UITextField *textField = (UITextField *)subSubview;
            [textField setKeyboardAppearance: UIKeyboardAppearanceAlert];
            textField.returnKeyType = UIReturnKeyDone;
            break;
        }
    }
}

我在寻找这个答案,因为旧的方法在iOS 7上已经无法使用了,谢谢! - Hugo Logmans
谢谢。为了使“完成”键真正关闭键盘,我还必须将视图控制器设置为文本字段的委托(在设置returnKeyType之前),并实现一个textFieldShouldReturn委托方法,其中包括[textField resignFirstResponder]。 - arlomedia
我还发现,在searchBarTextDidEndEditing中,我必须将textField的代理改回UISearchBar,使用另一组类似上面所示的循环。否则,如果我关闭键盘,然后再次尝试编辑搜索文本,它不会获得焦点并且第二次无法编辑。 - arlomedia
@arlomedia 不需要处理设置/取消UITextField委托,您仍然可以监听UISearchBarDelegate的searchBarSearchButtonClicked:。但我需要做的另一件事是textField.enablesReturnKeyAutomatically = NO;以便在空文本上可用Done。 - Andris Zalitis
1
现在有更好的方法吗? - GoodSp33d

10

尝试这样做:

for(UIView *subView in searchBar.subviews) {
    if([subView conformsToProtocol:@protocol(UITextInputTraits)]) {
        [(UITextField *)subView setKeyboardAppearance: UIKeyboardAppearanceAlert];
        [(UITextField *)subView setReturnKeyType:UIReturnKeyDone];
    }
}

如果你想去掉回车键(即让它不起作用),请将UITextField子视图的“returnKeyType”属性设置为“UIReturnKeyDone”,并将“keyboardAppearance”属性与其一起设置。


非常感谢@Neo,提供了一个有效的解决方案。UIView类的参考确实警告不要采用这种方法: “对于在UIKit和其他系统框架中声明的复杂视图,视图的任何子视图通常被认为是私有的,并且随时可能发生更改。因此,您不应尝试检索或修改这些类型的系统提供的视图的子视图。如果这样做,您的代码可能会在未来的系统更新中出现问题。” 这种方法是否安全适用于App Store?谢谢 - Andy Barnard
Andy,我知道至少有几个其他开发者这样做而没有遇到任何问题。此外,我们只是测试某个类的存在。因此,它是App Store安全的,因为我们没有使用任何私有API。 - Neo
谢谢解决方案!请问我可以知道在哪里放置这段代码吗?因为我尝试了在搜索栏开始编辑和在viewDidLoad中,但对我没有起作用。 - iOSDev
我把代码放在searchBarTextDidBeginEditing里面,它就可以工作了。 - arlomedia

2

我需要在Neo的回答基础上添加一些代码。以下是我为UISearchbar添加“完成”按钮的代码:

for(UIView *subView in sb_manSearch.subviews) {
    if([subView conformsToProtocol:@protocol(UITextInputTraits)]) {

        UITextField *t = (UITextField *)subView;
        [t setKeyboardAppearance: UIKeyboardAppearanceAlert];

        t.returnKeyType = UIReturnKeyDone;
        t.delegate = self;
        break;
    }
}

1
将搜索改为完成文本。 使用以下代码。
youtSearchBar.returnKeyType = .done

0

你可以通过以下方式实现:

- (void)viewDidLoad 
{
     // Adding observer that will tell you keyboard is appeared.
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) 
                                                 name:UIKeyboardDidShowNotification object:nil];        

    [super viewDidLoad];
}

- (void)keyboardDidShow:(NSNotification *)note 
{
    keyboardTest = [self getKeyboard];

    [keyboardTest setReturnKeyEnabled: YES];
}

- (id) getKeyboard  // Method that returns appeared keyboard's reference 
{
    id keyboardView;

    // locate keyboard view
    UIWindow* tempWindow = [[[UIApplication sharedApplication] windows] objectAtIndex:1];
    UIView* keyboard;

    for(int i=0; i<[tempWindow.subviews count]; i++) 
    {
        keyboard = [tempWindow.subviews objectAtIndex:i];

        if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 3.2) 
        {           
            if([[keyboard description] hasPrefix:@"<UIPeripheralHost"] == YES)
            {
                keyboard = [[keyboard subviews] objectAtIndex:0];
                keyboardView = keyboard ;
            }
        } 
        else
        {
            if([[keyboard description] hasPrefix:@"<UIKeyboard"] == YES)
                keyboardView = keyboard ;
        }

    }
    return keyboardView ;
}

0

更新:从iOS 7开始,接受的答案将不起作用,以下版本将在iOS 7及以上版本上工作。

 UIView *subViews =  [[_searchBar subviews] firstObject];
        for(UIView *subView in [subViews subviews]) {
            if([subView conformsToProtocol:@protocol(UITextInputTraits)]) {
                [(UITextField *)subView setEnablesReturnKeyAutomatically:NO];
            }
        }

0
for (UIView *subView in view.subviews) {
    if ([subView isKindOfClass:[UITextField class]])
    {
        UITextField *txt = (UITextField *)subView;

        @try {

            [txt setReturnKeyType:UIReturnKeyDone];
            [txt setKeyboardAppearance:UIKeyboardAppearanceAlert];
        }
        @catch (NSException * e) {

            // ignore exception
        }
    }
}

为了帮助 OP 解决当前的问题,可以在回答中添加一些解释说明。 - ρяσѕρєя K

-1

我刚刚发现了最简单的黑客方法,只需在开始编辑搜索字段时放置一个空白即可。

-(void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar{
    //Add a blank character to hack search button enable
    searchBar.text = @" ";}    

这个答案启用了搜索按钮,但是OP想把它改成返回或完成。 - arlomedia

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接