Cómo cambiar el texto predeterminado del botón Cancelar que aparece en UISearchBar + iPhone

HI Estoy desarrollando una aplicación en la que quería cambiar el texto de la cadena de búsqueda en SearchBar. Quería cambiar el texto del botón Cancelar también que aparece al lado de la barra de búsqueda. Antes de ingresar cualquier cadena en la barra de búsqueda obtendremos la cadena de búsqueda como la cadena por defecto. Quería cambiar el texto de esa cadena y cuando hacemos clic en esa barra de búsqueda obtenemos un botón de cancelar al lado de la barra de búsqueda y queremos cambiar el texto de ese botón de cancelación. Por favor, ayúdame.

También necesita tener el “searchBar setShowsCancelButton” antes del procedimiento.

- (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]; } } } 

Tenga en cuenta también: use UIButton para evitar problemas con Apple.

Usa el proxy de apariencia:

 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"]; 

Solución para iOS 7. Todos los créditos para esto van al Sr. Jesper Nielsen , quien escribió el código.

 -(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]; } } 

Si por “Cadena de búsqueda” te refieres al marcador de posición, entonces debería hacerlo:

 [searchBar setPlaceholder:@"Whatever you want"]; 

En cuanto a cambiar el texto del botón cancelar, puede ser un poco más difícil. Apple no usa un UIBarButtonItem estándar para esto, ni siquiera un UIButton no estándar. En su lugar, usan un UINavigationButton para el botón cancelar en la barra de búsqueda. Como esta no es una clase pública documentada, intentar modificarla bien podría hacer que tu aplicación sea rechazada desde la App Store. Si quieres arriesgar el rechazo, entonces puedes buscar a través de las subvistas de searchBar:

 for(UIView *view in [searchBar subviews]) { if([view isKindOfClass:[NSClassFromString(@"UINavigationButton") class]]) { [(UIBarItem *)view setTitle:@"Whatever you want"]; } } 

Tenga en cuenta que el botón Cancelar se carga de forma diferida, por lo que deberá realizar esta modificación cuando el usuario active la barra de búsqueda.

En iOS 7 si está utilizando UISearchBar, simplemente escriba este código en 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]; } } 

Me gustaría corregir la técnica UIAppearance, ya que el código yar1vn no funcionará con Xcode 5. Con lo siguiente, tendrás un código que funciona perfectamente para iOS 6 e iOS 7.

En primer lugar, debe entender que el botón cancelar es un UINavigationButton: UIButton privado. Por lo tanto, no es un UIBarButtonItem. Después de algunas inspecciones, parece que UINavigationButton responderá a esos selectores de 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:) 

Casualmente, esos selectores coinciden con los de un UIBarButtonItem. Lo que significa que el truco es usar dos UIAppearance separadas para manejar la clase privada UINavigationButton.

 /* dual appearance technique by Cœur to customize a UINavigationButton */ Class barClass = [UISearchBar self]; UIBarButtonItem *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 *buttonAppearanceInBar = [UIButton appearanceWhenContainedIn:barClass, nil]; [buttonAppearanceInBar setTitle:... forState:...]; 

Ahora, esta técnica funciona para el botón Cancelar, pero también funciona para el botón Atrás si cambia el barClass a [UINavigationBar self] .

Esta solución funciona para mí: iOs7 e iOs8:

 @interface ... : ... @property (strong, nonatomic) IBOutlet UISearchBar *search; @end 

y

 - (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]; } 

En iOS 7, si ha configurado displaysSearchBarInNavigationBar = YES en UISearchDisplayController , reemplazar el título del botón cancelar a través de la recursión de subvista o el proxy de aparición no funcionará .

En su lugar, use su propio botón de barra en 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; } 

Código de trabajo de Jeremytripp en Swift

No pude encontrar el mismo código en Swift, así que lo “traduje” yo mismo:

 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) } } } 

Si solo desea localizar el título predeterminado de “Cancelar” para cancelar, prefiero cambiar el valor de la clave CFBundleDevelopmentRegion de en a su región localizada en el archivo Info.plist en proyecto.

Aquí está mi cambio,

 CFBundleDevelopmentRegion zh_CN 

después de eso, el título predeterminado “Cancelar” se mostrará como chino “取消”. Este cambio también afectará a todos los valores de región predeterminados, por ejemplo, los títulos de acción de las operaciones de pasteboard en UITextField / UITextView estarán localizados, “Seleccionar” -> “选择”, “Pegar” -> “粘贴”, …

Por cierto, el archivo Info.plist podría ser localizado perfectamente.

¡Disfrutar!

En lugar de hacer referencia a la clase no pública UINavigationButton, hice lo siguiente. ¡Espero que lo haga a través de la revisión de la App Store!

 for (id subview in searchBar.subviews) { if ([subview respondsToSelector:@selector(setTitle:)]) { [subview setTitle:@"Map"]; } } 

Si sigues teniendo problemas para cambiar el botón Cancelar en iOS7, esto funciona actualmente para mí:

 -(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]; } } 

si SearchBar está en la barra de navegación, el código será diferente de la respuesta habitual; En su lugar, debe buscar las subvistas de 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]; } }} 

y Esto funciona en iOS7 +, si aún no puede establecer el título, debería aprender a ver la depuración: así resolví este problema mío.

Este breve tutorial describe los puntos clave de View-Debugging muy bien:

http://www.raywenderlich.com/98356/view-debugging-in-xcode-6

Código corto de trabajo en Swift 2.1 (iOS7-9 probado)

 @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) } } } }