7

How we can change the title of cancel button in search controller?

enter image description here

Almudhafar
  • 887
  • 1
  • 12
  • 26
  • I have written an answer to this topic here: http://stackoverflow.com/questions/19206757/how-to-change-textcolor-of-cancel-button-of-uisearchbar-in-ios7. Just use the SHSearchBar Cocoapod which is not such a pain in the ass like the UISearchBar. – blackjacx Nov 25 '16 at 12:41

11 Answers11

18

The solution provided above could change with new iOS releases. Here is a better approach:

[searchBar setValue:@"customString" forKey:@"_cancelButtonText"];
Zebs
  • 5,378
  • 2
  • 35
  • 49
Burhanuddin Sunelwala
  • 5,318
  • 3
  • 25
  • 51
  • 1
    `_cancelButtonText` is private, it may also change with new iOS releases if Apple decides to rename it, and because it's private they can safely presume that nobody is using this name in their apps – Gobe Apr 12 '17 at 02:35
  • I found this value can only be changed once as well. Any other solution where I can change the text (language) dynamically? – Joshua Vidamo Apr 13 '17 at 10:27
  • @JoshuaVidamo no its not only once, whenever you will call the above method, it will be changed. What exactly is your question? – Burhanuddin Sunelwala Apr 13 '17 at 11:13
  • 1
    This throws an exception when built on the iOS 13 SDK and the app is run on iOS 13. Is there an updated solution? – user102008 Jul 24 '19 at 17:30
  • @user102008 use the Appearance solution mentioned above. – Peter Suwara Aug 27 '19 at 13:30
11

The Swift equivalent of Burhanuddin Sunelwala answer did the trick for me!

self.searchBar.setValue("custom string", forKey: "cancelButtonText")

Thanks to Burhanuddin Sunelwala for putting me in the right direction!

NBoymanns
  • 686
  • 6
  • 16
8

You can change the "Cancel" Button in search bar using this-

for (UIView *view in searchBar.subviews)
{
    for (id subview in view.subviews)
    {
        if ( [subview isKindOfClass:[UIButton class]] )
        {
            [subview setEnabled:YES];
            UIButton *cancelButton = (UIButton*)subview;
            [cancelButton setTitle:@"hi" forState:UIControlStateNormal];


            NSLog(@"enableCancelButton");
            return;
        }
    }
}
user3575114
  • 993
  • 7
  • 13
4

Worth noting, that the preferred method for changing the Cancel button title is now via appearances (got the idea from an another question: https://stackoverflow.com/a/34522163/511878):

[[UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]] setTitle:@"Annuler"];
Community
  • 1
  • 1
gklka
  • 2,459
  • 1
  • 26
  • 53
3

You should use the appearance proxy of the UISearchBar. You can find an example here - How to change the default text of Cancel Button which appears in the UISearchBar +iPhone

Community
  • 1
  • 1
Yariv Nissim
  • 13,273
  • 1
  • 38
  • 44
2

swift version:

for view:UIView in (searchView?.subviews)!
{
        for subView:UIView in (view.subviews)
        {
            if ( subView is UIButton )
            {
                let cancelBut = subView as! UIButton

                //do stuff with cancelButton here
            }
        }
    }
Ashkan Ghodrat
  • 3,162
  • 2
  • 32
  • 36
1
for (UIView *subView in SearchBar.subviews) {
    if ([subView isKindOfClass:[UIButton class]]) {
        UIButton *cancelButton = (UIButton*)subView;

        [cancelButton setTitle:@"TitleString" forState:UIControlStateNormal];
}
sKhan
  • 9,694
  • 16
  • 55
  • 53
Vikesh Prasad
  • 779
  • 7
  • 13
1
  class ViewController: UIViewController,UISearchResultsUpdating {
        func updateSearchResults(for searchController: UISearchController) {
            //write your code here
        }
        @IBOutlet weak var navItem: UINavigationItem!
        let searchController = UISearchController(searchResultsController: nil)
        override func viewDidLoad() {
            super.viewDidLoad()
            searchController.obscuresBackgroundDuringPresentation = false
            searchController.definesPresentationContext = true
            searchController.searchResultsUpdater = self
            if #available(iOS 11.0, *){
                navigationItem.searchController = searchController
                UIBarButtonItem.appearance(whenContainedInInstancesOf: [UISearchBar.self]).title = "new title"
            }
            // Do any additional setup after loading the view.
        }
    }
1

swift 4 & 5

The best and simple way that worked for me is this snippet of code:

if let cancelButton = searchBar.value(forKey: "cancelButton") as? UIButton {
    cancelButton.setTitle("Annuler", for: .normal)
}

You can modify more properties like this:

if let cancelButton = searchBar.value(forKey: "cancelButton") as? UIButton {
    cancelButton.setTitle(<your_string>, for: <UIControlState>)
    cancelButton.setTitleColor(<your_uicolor>, for: <UIControlState>)
    cancelButton.setAttributedTitle(<your_nsattributedstring>, for: <UIControlState>)
}

I hope this helps :)

Soufiane ROCHDI
  • 1,543
  • 17
  • 24
0

You also need to have the searchBar setShowsCancelButton before the procedure.

- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller
{
    [theSearchBar setShowsCancelButton:YES animated:NO];
    for (UIView *subView in theSearchBar.subviews){
        if([subView isKindOfClass:[UIButton class]]){
            [(UIButton*)subView setTitle:@"Done" forState:UIControlStateNormal];
        }
    }
}

Note also use UIButton to avoid problems with Apple!

Abhishek Sharma
  • 3,283
  • 1
  • 13
  • 22
0

Swift 4.2, 4.0+

A custom class that supports many customizations with the below results is added in the answer here.

enter image description here

Kamran
  • 14,987
  • 4
  • 33
  • 51