我该如何更改 UISearchbar 取消按钮的文本颜色?

8
我有一个如下所示的UISearchBar。我该如何更改取消按钮的文本颜色?

enter image description here

6个回答

11
这个问题之前问过了,因此我认为提出问题的人已经找到了解决方案。但以防万一其他人遇到相同的问题,请看我的解决方案。
我有一个 UISearchBar,带有一个仅在 UISearchBar 的文本字段被点击时才出现的取消按钮。因此,覆盖 UISearchBar 子类中的 -(void)layoutSubviews 的解决方案对我来说不是一个选择。无论如何,我创建了一个 UISearchBar 的子类(CustomSearchBar),带有一个公共方法来设置取消按钮的字体和文本颜色。当我创建 UISearchBar 时,我确保搜索栏的文本字段委托设置为 self,创建搜索栏的类实现了 UITextFieldDelegate 协议。当用户点击搜索栏的文本字段时,它的代理会被通知并调用 CustomSearchBar 的方法。我在这里执行这个方法的原因是因为这时取消按钮出现了,因此我知道它在视图层次结构中且可以进行自定义。
以下是代码:
在 MyRootViewController 中创建 UISearchBar:
CustomSearchBar *searchBar = [[CustomSearchBar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 320.0f, 40)];
[searchBar setBarStyle:UIBarStyleDefault];
[searchBar setTintColor:[UIColor whiteColor]];

for (UIView *view in [searchBar subviews]) 
{
    if ([view isKindOfClass:[UITextField class]]) 
    {
        UITextField *searchTextField = (UITextField *)view;
        [searchTextField setDelegate:self];
    }
}

self.searchBar = searchBar;   
[searchBar release];

在MyRootViewController中实现UITextFieldDelegate(确保它实现了UITextFieldDelegate协议)

- (void)textFieldDidBeginEditing:(UITextField *)textField
{
    [self.searchBar setCloseButtonFont:[UIFont fontWithName:@"American Typewriter" size:14] textColor:[UIColor grayColor]];
}

这是UISearchBar子类中的公共方法

- (void)setCloseButtonFont:(UIFont *)font textColor:(UIColor *)textColor
{
    UIButton *cancelButton = nil;

    for(UIView *subView in self.subviews)
    {
        if([subView isKindOfClass:[UIButton class]])
        {
            cancelButton = (UIButton*)subView;
        }
    }

    if (cancelButton)
    {
        /* For some strange reason, this code changes the font but not the text color. I assume some other internal customizations      make this not possible:

        UILabel *titleLabel = [cancelButton titleLabel];
        [titleLabel setFont:font];
        [titleLabel setTextColor:[UIColor redColor]];*/

        // Therefore I had to create view with a label on top:        
        UIView *overlay = [[UIView alloc] initWithFrame:CGRectMake(2, 2, kCancelButtonWidth, kCancelButtonLabelHeight)];
        [overlay setBackgroundColor:[UIColor whiteColor]];
        [overlay setUserInteractionEnabled:NO]; // This is important for the cancel button to work
        [cancelButton addSubview:overlay];

        UILabel *newLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 2, kCancelButtonWidth, kCancelButtonLabelHeight)];
        [newLabel setFont:font];
        [newLabel setTextColor:textColor];
        // Text "Cancel" should be localized for other languages
        [newLabel setText:@"Cancel"]; 
        [newLabel setTextAlignment:UITextAlignmentCenter];
        // This is important for the cancel button to work
        [newLabel setUserInteractionEnabled:NO]; 
        [overlay addSubview:newLabel];
        [newLabel release];
        [overlay release]; 
    }
}

太棒了,谢谢你。我之前使用了一种替代方法,但我并不是很满意。但现在我可以重新解决这个问题了。感谢! - Zhen

7

不要做所有那些花哨的事情,只需要像这样实现 SearchBarTextDidBeginEditing

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
    // only show the status bar’s cancel button while in edit mode sbar (UISearchBar)
    searchBar.showsCancelButton = YES;
    searchBar.autocorrectionType = UITextAutocorrectionTypeNo;
    UIColor *desiredColor = [UIColor colorWithRed:212.0/255.0 green:237.0/255.0 blue:187.0/255.0 alpha:1.0];


    for (UIView *subView in searchBar.subviews){
        if([subView isKindOfClass:[UIButton class]]){
            NSLog(@"this is button type");

            [(UIButton *)subView setTintColor:desiredColor];
            [(UIButton *)subView setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        }
}

4

Gyanerdra的回答很好。但是在iOS7中,我需要做出以下更改才能使它在我的应用程序中起作用。

NSArray *childViews;
if ( (APP).isIOS7 ) {
    childViews = [[searchBar.subviews objectAtIndex:0] subviews];
} else {
    childViews =searchBar.subviews;
}

for (UIView *subView in childViews ) {
    if([subView isKindOfClass:[UIButton class]]){
        [(UIButton *)subView setTintColor:desiredColor];
        [(UIButton *)subView setTitleColor:desiredColor forState:UIControlStateNormal];
    }
}

看起来在iOS7中,搜索栏被包含在一个父视图中。 希望这能帮助到某些人。 b


2

您可以创建 UISearchBar 的子类,并编写自己的 - (void)layoutSubviews 方法。在此方法中,循环遍历其子视图并获取 cancelButton。其余部分应该是直截了当的。


谢谢你的回答。但是我对如何重写layoutSubView方法不太熟悉。你能帮助指导我吗? - Zhen
只有在 UISearchBar 的 showsCancelButton 属性设置为 YES 时,重写 -(void)layoutSubviews 才能起作用。默认情况下,该属性设置为 NO,因此,取消按钮仅在点击 UISearchBar 的文本字段后才会出现。在这种情况下,重写 layoutSubviews 将没有任何效果。 - strave

0

1
在您无法启用searchBar.showsCancelButton = YES之前,获取cancelButton = nil。 - kb920

0

KVC

UIButton *button = [_searchBar valueForKey:@"_cancelButton"]; button.titleLabel.font = [UIFont systemFontOfSize:13];

KVC

UIButton *button = [_searchBar valueForKey:@"_cancelButton"]; button.titleLabel.font = [UIFont systemFontOfSize:13];


1
这似乎影响字体大小,而不是颜色。 - ouflak
所以,你可以更改字体,也可以更改标题颜色。[button setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal]; - fengbai

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