How to change the default text of Cancel Button which appears in the UISearchBar +iPhone

后端 未结 15 1968
慢半拍i
慢半拍i 2020-12-01 03:04

I am developing an Application where I wanted to change the text of Search String in the SearchBar. I wanted to change the text of Cancel Button Also which appears next to t

相关标签:
15条回答
  • 2020-12-01 03:21

    Solution for iOS 7. All credits for this go to Mr. Jesper Nielsen - he wrote the code.

    -(void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller {
        UIButton *cancelButton;
        UIView *topView = theSearchBar.subviews[0];
        for (UIView *subView in topView.subviews) {
            if ([subView isKindOfClass:NSClassFromString(@"UINavigationButton")]) {
                cancelButton = (UIButton*)subView;
            }
        }
        if (cancelButton) {
            [cancelButton setTitle:@"YourTitle" forState:UIControlStateNormal];
        }
    
    }
    
    0 讨论(0)
  • 2020-12-01 03:23

    Use the appearance proxy:

    id barButtonAppearanceInSearchBar = [UIBarButtonItem appearanceWhenContainedIn:[UISearchBar class], nil];
    
    [barButtonAppearanceInSearchBar setBackgroundImage:grayBackgroundImage forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
    [barButtonAppearanceInSearchBar setTitleTextAttributes:@{
                                          NSFontAttributeName : [UIFont fontWithName:@"HelveticaNeue-CondensedBold" size:20],
                                     NSForegroundColorAttributeName : [UIColor blackColor]
         } forState:UIControlStateNormal];
    [barButtonAppearanceInSearchBar setTitle:@"X"];
    
    0 讨论(0)
  • 2020-12-01 03:23

    Instead of referencing the non-public UINavigationButton class, I did the following. I'm hoping that it will make it through App Store review!

    for (id subview in searchBar.subviews) {
        if ([subview respondsToSelector:@selector(setTitle:)]) {
            [subview setTitle:@"Map"];
        }
    }
    
    0 讨论(0)
  • 2020-12-01 03:25

    I would like to fix the UIAppearance technique, as yar1vn code won't work with Xcode 5. With the following you will have code that works perfectly for both iOS 6 and iOS 7.

    First, you need to understand that the cancel button is a private UINavigationButton:UIButton. Hence, it is not an UIBarButtonItem. After some inspection, it appears that UINavigationButton will respond to those UIAppearance selectors:

    // inherited from UINavigationButton
    @selector(setTintColor:)
    @selector(setBackgroundImage:forState:style:barMetrics:)
    @selector(setBackgroundImage:forState:barMetrics:)
    @selector(setTitleTextAttributes:forState:)
    @selector(setBackgroundVerticalPositionAdjustment:forBarMetrics:)
    @selector(setTitlePositionAdjustment:forBarMetrics:)
    @selector(setBackButtonBackgroundImage:forState:barMetrics:)
    @selector(setBackButtonTitlePositionAdjustment:forBarMetrics:)
    @selector(setBackButtonBackgroundVerticalPositionAdjustment:forBarMetrics:)
    
    // inherited from UIButton
    @selector(setTitle:forState:)
    

    Coincidentally, those selectors match those of a UIBarButtonItem. Meaning the trick is to use two separate UIAppearance to handle the private class UINavigationButton.

    /* dual appearance technique by Cœur to customize a UINavigationButton */
    Class barClass = [UISearchBar self];
    
    UIBarButtonItem<UIAppearance> *barButtonItemAppearanceInBar = [UIBarButtonItem appearanceWhenContainedIn:barClass, nil];
    [barButtonItemAppearanceInBar setTintColor:...];
    [barButtonItemAppearanceInBar setBackgroundImage:... forState:... style:... barMetrics:...];
    [barButtonItemAppearanceInBar setBackgroundImage:... forState:... barMetrics:...];
    [barButtonItemAppearanceInBar setTitleTextAttributes:... forState:...];
    [barButtonItemAppearanceInBar setBackgroundVerticalPositionAdjustment:... forBarMetrics:...];
    [barButtonItemAppearanceInBar setTitlePositionAdjustment:... forBarMetrics:...];
    [barButtonItemAppearanceInBar setBackButtonBackgroundImage:... forState:... barMetrics:...];
    [barButtonItemAppearanceInBar setBackButtonTitlePositionAdjustment:... forBarMetrics:...];
    [barButtonItemAppearanceInBar setBackButtonBackgroundVerticalPositionAdjustment:... forBarMetrics:...];
    
    UIButton<UIAppearance> *buttonAppearanceInBar = [UIButton appearanceWhenContainedIn:barClass, nil];
    [buttonAppearanceInBar setTitle:... forState:...];
    

    Now, this technique works for the Cancel button, but it also works for the Back button if you change the barClass to [UINavigationBar self].

    0 讨论(0)
  • 2020-12-01 03:25

    Working short code in Swift 2.1 (iOS7-9 tested)

    @IBOutlet weak var searchBar: UISearchBar!
    func enableSearchBarCancelButton(enable: Bool, title: String? = nil) {
        searchBar?.showsCancelButton = enable
        if enable {
            if let _cancelButton = searchBar?.valueForKey("_cancelButton"),
                let cancelButton = _cancelButton as? UIButton {
                    cancelButton.enabled = enable //comment out if you want this button disabled when keyboard is not visible
                    if title != nil {
                        cancelButton.setTitle(title, forState: UIControlState.Normal)
                    }
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-01 03:26

    On iOS 7, if you've set displaysSearchBarInNavigationBar = YES on UISearchDisplayController, replacing the cancel button title via subview recursion or the appearance proxy will not work.

    Instead, use your own bar button in viewDidLoad:

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        self.searchDisplayController.displaysSearchBarInNavigationBar = YES;
        UIBarButtonItem *barItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"A Custom Title", nil)
                                                                    style:UIBarButtonItemStyleBordered
                                                                   target:self
                                                                   action:@selector(cancelButtonTapped:)];
    
        // NB: Order is important here.
        //     Only do this *after* setting displaysSearchBarInNavigationBar to YES
        //     as that's when UISearchDisplayController creates it's navigationItem
        self.searchDisplayController.navigationItem.rightBarButtonItem = barItem;
    }
    
    0 讨论(0)
提交回复
热议问题