更改 UISearchBar/键盘搜索按钮标题

61
在 UISearchBar 控件中,是否有一种方法可以更改键盘搜索键的标题为“完成”?

这里我解释了http://stackoverflow.com/a/26712861/2981840 - Chidhambaram
10个回答

99

对于名为tablesearchbar的搜索栏:

// Set the return key and keyboard appearance of the search bar
        for (UIView *searchBarSubview in [tableSearchBar subviews]) {

            if ([searchBarSubview conformsToProtocol:@protocol(UITextInputTraits)]) {

                @try {

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

                    // ignore exception
                }
            }
        }

这个能通过App Store的审核流程吗? - zekel
4
由于没有访问私有API,因此不应拒绝批准。 - RunLoop
2
很好的答案。额外注意事项:我更喜欢在if语句中添加第二个条件,而不是使用@try-@catch(因为我们知道在objective-C中它们并不便宜且优化得很好): && [searchBarSubview isKindOfClass:[UITextField class]] 以摆脱@try-catch。 - Andrea Sprega
6
在iOS 7中,对子视图的循环遍历对我没起作用,但是对子视图的子视图进行循环遍历可以成功(请参见我的答案)。 - Gregory Cosmo Haun
//如果你不在主线程上,请在“setReturnKeyType”之后插入以下内容: [(UITextField *)searchBarSubview performSelectorOnMainThread:@selector(reloadInputViews) withObject:nil waitUntilDone:NO]; - codrut
对我不起作用,我已经发布了我的问题。请帮助我。 - Pradip Vanparia

52

至少对于iOS 8,只需:

    [self.searchBar setReturnKeyType:UIReturnKeyDone];

43

截至iOS 7 beta 5,RunLoop的答案对我没有用,但这个可以:

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

5
以防不清楚,if/else 的使用原因是 if 用于 iOS 6 向后兼容性,else 用于 iOS 7。 - James Kuang

18

如何更改UISearchBar的返回键

searchBar.returnKeyType = UIReturnKeyType.done

可用的枚举如下所示:

public enum UIReturnKeyType : Int {

    case default
    case go
    case google
    case join
    case next
    case route
    case search
    case send
    case yahoo
    case done
    case emergencyCall
    @available(iOS 9.0, *)
    case continue
}

18

一个更加有用的提示,关于运行循环代码(在"@try"部分)。

当文本字段为空时,这将使“完成”按钮可用:

UITextField *tf = (UITextField *)searchBarSubview;
tf.enablesReturnKeyAutomatically = NO;

1
谢谢!这也适用于Gregory针对iOS7的解决方案。 - jbandi

3

提醒一下!如果您的搜索栏仍然是第一个响应者,在更改了returnKeyType后,您需要关闭键盘并再次弹出键盘才能看到更改。

search.resignFirstResponder()
searchBar.returnKeyType = UIReturnKeyType.Done
search.becomeFirstResponder()

1
作为一个带有可选方法的协议,您应该单独测试每个方法而不是使用 try-catch。
for (UIView *searchBarSubview in searchBar.subviews)
{
    if ([searchBarSubview conformsToProtocol:@protocol(UITextInputTraits)])
    {
        // keyboard appearance
        if ([searchBarSubview respondsToSelector:@selector(setKeyboardAppearance:)])
            [(id<UITextInputTraits>)searchBarSubview setKeyboardAppearance:UIKeyboardAppearanceAlert];
        // return key 
        if ([searchBarSubview respondsToSelector:@selector(setReturnKeyType:)])
            [(id<UITextInputTraits>)searchBarSubview setReturnKeyType:UIReturnKeyDone];
        // return key disabled when empty text
        if ([searchBarSubview respondsToSelector:@selector(setEnablesReturnKeyAutomatically:)])
            [(id<UITextInputTraits>)searchBarSubview setEnablesReturnKeyAutomatically:NO];
        // breaking the loop when we are done
        break;
    }
}

这将适用于 iOS <= 6。对于 iOS >= 7,您需要循环使用 searchBar.subviews[0].subviews


0

由于警报样式键盘是半透明的,我可以看到它后面的视图。这并不好看,因为在键盘后面有多个元素,这使得键很难突出。我想要一个全黑色的键盘。

所以当编辑文本时,我会将一个黑色的UIImageView动画移动到键盘后面的位置。这就呈现了一个全黑色的键盘外观。

- (void)textFieldDidBeginEditing:(UITextField *)textField {

    [UIView beginAnimations:nil context:nil];
    [UIView setAnimationDuration:0.25]; 

    blackBoxForKeyboard.frame = CGRectMake(0, 377, 320, 216);
    [UIView commitAnimations]; 

}

0

为了覆盖所有的iOS版本:

NSArray *subviews = [[[UIDevice currentDevice] systemVersion] floatValue] < 7 ? _searchBar.subviews : _searchBar.subviews[0].subviews;

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

0

我尝试了所有在这里展示的解决方案,但没有一个适用于我的UISearchBar(xcode5编译iOS7)。最终我使用了以下递归函数,它对我有用:

- (void)fixSearchBarKeyboard:(UIView*)searchBarOrSubView {

    if([searchBarOrSubView conformsToProtocol:@protocol(UITextInputTraits)]) {
        if ([searchBarOrSubView respondsToSelector:@selector(setKeyboardAppearance:)])
            [(id<UITextInputTraits>)searchBarOrSubView setKeyboardAppearance:UIKeyboardAppearanceAlert];
        if ([searchBarOrSubView respondsToSelector:@selector(setReturnKeyType:)])
            [(id<UITextInputTraits>)searchBarOrSubView setReturnKeyType:UIReturnKeyDone];
        if ([searchBarOrSubView respondsToSelector:@selector(setEnablesReturnKeyAutomatically:)])
            [(id<UITextInputTraits>)searchBarOrSubView setEnablesReturnKeyAutomatically:NO];
    }

    for(UIView *subView in [searchBarOrSubView subviews]) {
        [self fixSearchBarKeyboard:subView];
    }
}

然后我这样调用它:

_searchBar = [[UISearchBar alloc] init];
[self fixSearchBarKeyboard:_searchBar];

使用Xcode 5 + iOS7,文本输入将位于子子视图而不是子视图中。因此,基本上您使用了我的Xcode 4解决方案并添加了递归调用。为了获得最佳性能,您可以测试iOS版本,如果是iOS7,则浏览subviews[0].subviews而不是subviews - Cœur

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