我正在开发一个应用程序,我想在SearchBar中更改搜索字符串的文本。我想更改SearchBar旁边显示的取消按钮的文本。在搜索栏中输入任何字符串之前,我们将获取搜索字符串作为默认字符串。我想更改该字符串的文本,当我们点击该搜索栏时,我们会在搜索栏旁边找到一个取消按钮,我想更改该取消按钮的文本。
答案 0 :(得分:50)
使用外观代理:
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"];
答案 1 :(得分:35)
您还需要在程序之前使用“searchBar setShowsCancelButton”。
- (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];
}
}
}
另请注意:使用UIButton来避免Apple问题!
答案 2 :(得分:23)
iOS 7的解决方案。所有学分转到Mr. Jesper Nielsen - 他编写了代码。
-(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];
}
}
答案 3 :(得分:4)
如果通过“搜索字符串”表示占位符,那么应该这样做:
[searchBar setPlaceholder:@"Whatever you want"];
至于更改取消按钮的文本,可能会有点困难。 Apple不会为此使用标准的UIBarButtonItem,甚至不使用非标准的UIButton。相反,他们在搜索栏中使用UINavigationButton作为取消按钮。由于这不是一个记录在案的公共类,因此尝试修改它可能会使您的应用程序从App Store中被拒绝。如果您确实想要拒绝风险,那么您可以搜索searchBar的子视图:
for(UIView *view in [searchBar subviews]) {
if([view isKindOfClass:[NSClassFromString(@"UINavigationButton") class]]) {
[(UIBarItem *)view setTitle:@"Whatever you want"];
}
}
请注意,取消按钮是懒惰加载的,因此当用户激活搜索栏时,您必须进行此修改。
答案 4 :(得分:4)
在iOS 7中,如果您使用的是UISearchBar,只需在searchBarTextDidBeginEditing:method
中编写此代码searchBar.showsCancelButton = YES;UIView* view=searchBar.subviews[0];
for (UIView *subView in view.subviews) {
if ([subView isKindOfClass:[UIButton class]]) {
UIButton *cancelButton = (UIButton*)subView;
[cancelButton setTitle:@"إلغاء" forState:UIControlStateNormal];
}
}
答案 5 :(得分:3)
我想修复UIAppearance技术,因为yar1vn代码不适用于Xcode 5.下面你将拥有适用于iOS 6和iOS 7的代码。
首先,您需要了解取消按钮是私有的UINavigationButton:UIButton。因此,它不是UIBarButtonItem。经过一番检查后,UINavigationButton似乎会回应那些UIAppearance选择器:
// 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:)
巧合的是,这些选择器与UIBarButtonItem匹配。这意味着使用两个单独的UIAppearance来处理私有类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:...];
现在,此技术适用于“取消”按钮,但如果将barClass更改为[UINavigationBar self]
,它也适用于“后退”按钮。
答案 6 :(得分:2)
此解决方案适用于我 - iOs7和iOs8:
@interface ... : ...
@property (strong, nonatomic) IBOutlet UISearchBar *search;
@end
和
- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar {
[searchBar setShowsCancelButton:YES animated:YES];
NSArray *searchBarSubViews = [[self.search.subviews objectAtIndex:0] subviews];
UIButton *cancelButton;
for (UIView *subView in searchBarSubViews) {
if ([subView isKindOfClass:NSClassFromString(@"UINavigationButton")]) {
cancelButton = (UIButton*)subView;
break;
}
}
if (cancelButton) {
[cancelButton setTitle:@"New cancel" forState:UIControlStateNormal];
}
//insert this two lines below if you have a button appearance like this "Ne...cel"
[searchBar setShowsCancelButton:NO animated:YES];
[searchBar setShowsCancelButton:YES animated:YES];
}
答案 7 :(得分:1)
在iOS 7上,如果您在displaysSearchBarInNavigationBar = YES
上设置了UISearchDisplayController
,则通过子视图递归替换取消按钮标题或外观代理将无效。
相反,请使用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;
}
答案 8 :(得分:1)
Jeremytripp在Swift工作的代码
我无法在Swift中找到相同的代码,所以我&#34;翻译了#34;我自己:
func searchDisplayControllerWillBeginSearch(controller: UISearchDisplayController) {
self.searchDisplayController?.searchBar.showsCancelButton = true
var cancelButton: UIButton
var topView: UIView = self.searchDisplayController?.searchBar.subviews[0] as UIView
for subView in topView.subviews {
if subView.isKindOfClass(NSClassFromString("UINavigationButton")) {
cancelButton = subView as UIButton
cancelButton.setTitle("My Custom Title", forState: UIControlState.Normal)
}
}
}
答案 9 :(得分:1)
如果您只想本地化取消按钮的默认“取消”标题,我更喜欢将 CFBundleDevelopmentRegion 键的值从en更改为Info中的本地化区域项目中的.plist文件。
这是我的更改,
<key>CFBundleDevelopmentRegion</key>
<string>zh_CN</string>
之后,默认的“取消”标题将显示为中文“取消”。此更改还将影响所有默认区域值,例如,UITextField / UITextView上的粘贴板操作的操作标题将被本地化,“选择” - &gt; “选择”,“粘贴” - &gt; “粘贴” ...
顺便说一句,Info.plist文件可以完美地进行本地化。
享受!
答案 10 :(得分:0)
我没有引用非公共UINavigationButton类,而是执行了以下操作。我希望它能通过App Store审核!
for (id subview in searchBar.subviews) {
if ([subview respondsToSelector:@selector(setTitle:)]) {
[subview setTitle:@"Map"];
}
}
答案 11 :(得分:0)
如果您在更改iOS7中的“取消”按钮时仍然遇到问题,目前这对我有用:
-(void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller{
self.searchDisplayController.searchBar.showsCancelButton = YES;
UIButton *cancelButton;
UIView *topView = self.searchDisplayController.searchBar.subviews[0];
for (UIView *subView in topView.subviews) {
if ([subView isKindOfClass:NSClassFromString(@"UINavigationButton")]) {
cancelButton = (UIButton*)subView;
}
}
if (cancelButton) {
//Set the new title of the cancel button
[cancelButton setTitle:@"Hi" forState:UIControlStateNormal];
}
}
答案 12 :(得分:0)
如果SearchBar在navigationBar中,代码将与通常的答案不同;您需要搜索NavigationBar的子视图。
-(void)searchDisplayControllerDidBeginSearch:(UISearchDisplayController *)controller{
UINavigationBar * navigationBar = self.navigationController.navigationBar;
for (UIView *subView in navigationBar.subviews){
if([subView isKindOfClass:NSClassFromString(@"UINavigationButton")]){
[(UIButton*)subView setTitle:@"İptal" forState:UIControlStateNormal];
}
}}
并且这项工作在iOS7 +中,如果你仍然无法设置标题,你应该学习查看调试 - 这就是我解决这个问题的方法。
这个简短的教程非常清楚地概述了View-Debugging的关键点:
http://www.raywenderlich.com/98356/view-debugging-in-xcode-6
答案 13 :(得分:0)
if #available(iOS 13.0, *) {
controller.searchBar.setValue("Done", forKey:"cancelButtonText")
} else {
controller.searchBar.setValue("Done", forKey:"_cancelButtonText")
}
?♂️
实际上controller.searchBar.setValue("Done", forKey:"cancelButtonText")
适用于所有iOS版本
答案 14 :(得分:-1)
在Swift 2.1中运行短代码(已测试iOS7-9)
@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)
}
}
}
}