Is there any way to change the text font and color of the UISearchBar Cancel button without subclassing the searchbar?
11 Answers
You can change Cancel button styling by changing the appearance of UIBarButtonItem
when contained in UISearchBar
.
For example,
[[UIBarButtonItem appearanceWhenContainedIn:[UISearchBar class], nil] setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:
[UIColor blueColor],
UITextAttributeTextColor,
[UIColor darkGrayColor],
UITextAttributeTextShadowColor,
[NSValue valueWithUIOffset:UIOffsetMake(0, -1)],
UITextAttributeTextShadowOffset,
nil]
forState:UIControlStateNormal];
If you just want to modify Cancel button, you can do it by:
if let cancelButton = searchBar.valueForKey("cancelButton") as? UIButton {
cancelButton.setTitle(<your_string>, forState: <UIControlState>)
cancelButton.setTitleColor(<your_uicolor>, forState: <UIControlState>)
cancelButton.setAttributedTitle(<your_nsattributedstring>, forState: <UIControlState>)
}
where searchBar
is your UISearchBar
object.
Based on htinlinn's answer, this is what I used in my viewDidLoad
method of the view controller using the search bar in iOS 7:
[[UIBarButtonItem appearanceWhenContainedIn:[UISearchBar class], nil]
setTitleTextAttributes:[NSDictionary dictionaryWithObjectsAndKeys:[UIColor whiteColor], NSForegroundColorAttributeName, nil]
forState:UIControlStateNormal];
Simplified Swift version of @htinlinn answer:
let attributes = [
NSForegroundColorAttributeName : UIColor.textBlueColor,
NSFontAttributeName : UIFont.systemFontOfSize(13)
]
UIBarButtonItem.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).setTitleTextAttributes(attributes, forState: .Normal)
For modifying the search bar cancel button you have take Button object and change the reference of that button to your custom button.
UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(50,20,300,30)]; searchBar.delegate = self; searchBar.barStyle = UIBarStyleDefault; searchBar.showsCancelButton = YES; UIButton *cancelButton; for (id button in searchBar.subviews) { if ([button isKindOfClass:[UIButton class]]) { cancelButton=(UIButton*)button; break; } }
You can use the tint property of searchBar to change the color of searchBar, cancel button's color will get changed but according to the color of UISearchBar. I can't be edited manually. But you can always put a custom over it in the interface builder which will hide the native cancel button. And the user will use your custom button as the cancel button of the searchBar.
Swift solution after iOS 9.0 (by modifying htinlinn's answer):
if #available(iOS 9.0, *) {
UIBarButtonItem.appearanceWhenContainedInInstancesOfClasses([UISearchBar.classForCoder()])
.setTitleTextAttributes([
NSFontAttributeName: UIFont.systemFontOfSize(12),
NSForegroundColorAttributeName: UIColor.blueColor(),
NSShadowAttributeName: NSShadow(color: UIColor.redColor(), offset: CGSizeMake(0, -1), blurRadius: 2)
],
forState: UIControlState.Normal)
} else {
// Link to Objective-C Method
}
And the current Objective-C method (UITextAttributeTextColor
is deprecated since iOS 7.0):
[[UIBarButtonItem appearanceWhenContainedIn:[UISearchBar class], nil]
setTitleTextAttributes:@{
NSForegroundColorAttributeName: [UIColor blueColor],
NSFontAttributeName: [UIFont systemFontOfSize:12]}
forState:UIControlStateNormal];
My little shadow extension used in the code above:
extension NSShadow {
convenience init(color: AnyObject!, offset: CGSize, blurRadius: CGFloat) {
self.init()
self.shadowColor = color
self.shadowOffset = offset
self.shadowBlurRadius = blurRadius
}
}
A much better solution here
UIButton *cancelButton = [searchBar valueForKey:@"_cancelButton"];
[cancelButton setTitleColor:[UIColor yourColor] forState:UIControlStateNormal];
[cancelButton setTitle:@"Your Text" forState:UIControlStateNormal];
and similarly you can change other style and text properties of the button.
For iOS 13.* (@AnujAroshA answer in comments)
UIButton *cancelButton = [searchBar valueForKey:@"cancelButton"];