当点击取消按钮时,删除UISearchBar右侧的清除按钮(灰色x)

时间:2010-06-16 10:14:16

标签: iphone objective-c ipad interface-builder

是的,开始我的问题,这里有Spotify应用程序已经解决的问题的一些屏幕:

Spotify的第1步:标准UISearchBar未处于编辑模式。

Step 1 http://i49.tinypic.com/wbtpwi.png

Spotify的第2步: UISearchBar现在处于编辑模式。已输入搜索字词。取消按钮从右侧滑入,出现清除按钮(灰色x)。

Step 2 http://i45.tinypic.com/161kbvp.png

Spotify的第3步:按下取消按钮;键盘滑出,搜索栏不再处于编辑模式。搜索字词仍然存在,灰色x按钮现已隐藏

Step 3 http://i46.tinypic.com/20utv9v.png

目前,当按下我的取消按钮时,以下代码会触发:

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
    [searchBar resignFirstResponder];
    [searchBar setShowsCancelButton:NO animated:YES];
}

结果是:

我的第3步:搜索栏现在未处于编辑模式。取消按钮和键盘已滑出。搜索词仍然存在,但灰色x也是如此。

Problem http://i46.tinypic.com/rlm4w5.png

所以,我的问题是:假设-resignFirstResponder(和-endEditing:,FYI)在搜索栏输入文字时隐藏灰色x按钮它,怎么隐藏它?

再次感谢,朋友们。

11 个答案:

答案 0 :(得分:29)

问题是UISearchBar不公开它的文本字段,并管理文本字段本身的属性。有时,属性的值不是您想要的。

例如,在我自己的应用程序中,我希望搜索栏的键盘样式使用透明警报样式。

我的解决方案是遍历搜索栏的子视图,直到找到文本字段。然后,您应该能够使用clearButtonMode等参数设置UITextFieldViewModeWhileEditing属性。

这应该使得仅在文本字段编辑时显示清除按钮。

你想在viewDidLoad或早期的事情上做这件事,所以在你开始使用它之前就已经设定了(但是在搜索栏初始化之后。

for (UIView *subview in searchBar.subviews)
{
    if ([subview conformsToProtocol:@protocol(UITextInputTraits)])
    {
        [(UITextField *)subview setClearButtonMode:UITextFieldViewModeWhileEditing];
    }
}

答案 1 :(得分:6)

看起来iOS 7改变了UISearchBar的视图层次结构,文本框在视图中更深(上面的解决方案对我不起作用)。但是,修改上述解决方案以遍历整个层次结构有效:

[self configureSearchBarView:[self searchBar]];

- (void)configureSearchBarView:(UIView*)view {
    for (UIView *subview in [view subviews]){
        [self configureSearchBarView:subview];
    }
    if ([view conformsToProtocol:@protocol(UITextInputTraits)]) {
        [(UITextField *)view setClearButtonMode:UITextFieldViewModeWhileEditing];
    }
}

答案 2 :(得分:6)

我正在以前的答案为基础,因为我开始在iOS 7.1上看到崩溃,除非我做了以下更改。我为每个视图添加了对respondsToSelector的附加调用,以确保可以调用setClearButtonMode:。我观察到一个UISearchBar传入的实例,它似乎符合UITextInputTraits协议,但没有setClearButtonMode:选择器,因此发生了崩溃。 UISearchBarTextField的实例也会被传入,并且是要调用setClearButtonMode:的实际对象。

- (void)removeClearButtonFromView:(UIView *)view
{
    if (!view)
    {
        return;
    }

    for (UIView *subview in view.subviews)
    {
        [self removeClearButtonFromView:subview];
    }

    if ([view conformsToProtocol:@protocol(UITextInputTraits)])
    {
        UITextField *textView = (UITextField *)view;
        if ([textView respondsToSelector:@selector(setClearButtonMode:)])
        {
            [textView setClearButtonMode:UITextFieldViewModeNever];
        }
    }
}

答案 3 :(得分:4)

在iOS7中更好的方法是:

[[UITextField appearanceWhenContainedIn:[UISearchBar class], nil] setClearButtonMode:UITextFieldViewModeWhileEditing];

答案 4 :(得分:4)

您需要获取搜索栏的textField

UITextField *textField = [searchBar valueForKey:@"_searchField"];
textField.clearButtonMode = UITextFieldViewModeNever;

使用 - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar方法。

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
 {

UITextField *textField = [searchBar valueForKey:@"_searchField"];
textField.clearButtonMode = UITextFieldViewModeNever;


 }

答案 5 :(得分:3)

要扩展Jadariens的答案,如果您从未希望灰色x出现,则需要使用以下

for (UIView *subview in searchBar.subviews)
{
    if ([subview conformsToProtocol:@protocol(UITextInputTraits)])
    {
        [(UITextField *)subview setClearButtonMode:UITextFieldViewModeNever];
    }
}

答案 6 :(得分:1)

接受的答案在iOS7 +上不起作用,这是作为Swift扩展名的修改版本

extension UIView {
    class func removeClearButton(svs: [UIView]) {
        for sv in svs {
            if let tv = sv as? UITextField where sv.conformsToProtocol(UITextInputTraits) {
                tv.clearButtonMode = .Never
                return
            } else {
                UIView.removeClearButton(sv.subviews)
            }
        }
    }
}

用法

UIView.removeClearButton(searchBar.subviews)

答案 7 :(得分:0)

她是我写的一个类别

分类

@implementation UISearchBar (Additions)

- (void)setClearButtonMode:(UITextFieldViewMode)viewMode {
    UITextField *textField = [self findTextFieldInView:self];
    [textField setClearButtonMode:viewMode];
}

- (UITextField *)findTextFieldInView:(UIView *)view {

    for (UIView *subview in view.subviews) {

        if ([subview isKindOfClass:[UITextField class]] ||
            [subview.class isSubclassOfClass:[UITextField class]]) {

            return (UITextField *)subview;
        }

        UITextField *textField = [self findTextFieldInView:subview];

        if (textField) {
            return textField;
        }
    }

    return nil;
}

@end

用法

[searchBar setClearButtonMode:UITextFieldViewModeWhileEditing];

答案 8 :(得分:0)

这里的答案比任何答案都要好,而且您不必使用私有API或遍历子视图来执行此操作。

UISearchBar有一个用于执行此操作的内置API:

[UISearchBar setImage:forSearchBarIcon:state]

你想要的SearchBar图标键是UISearchBarIconClear,你想要UIControlStateNormal状态。然后给它一个清晰的图像,你就完成了。

所以,它应该是这样的:

[searchBar setImage:clearImage forSearchBarIcon:UISearchBarIconClear state:UIControlStateNormal];

答案 9 :(得分:0)

对于searchBar中的(x)图标。您可以使用以下委托方法。

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
    searchBar.showsCancelButton = YES;
}

答案 10 :(得分:0)

for (UIView *subview in _search_bar.subviews)
{
    NSLog(@"%@",subview.subviews);

    for (UIView *subview11 in subview.subviews)
    {
        if ([subview11 conformsToProtocol:@protocol(UITextInputTraits)])
        {
            [(UITextField *)subview11 setClearButtonMode:UITextFieldViewModeNever];
        }
    }

}