[英]How to change the default text of Cancel Button which appears in the UISearchBar +iPhone
我正在開發一個應用程序,我想在其中更改 SearchBar 中搜索字符串的文本。 我想更改出現在 SearchBar 旁邊的 Cancel Button Also 的文本。 在搜索欄中輸入任何字符串之前,我們將獲得搜索字符串作為默認字符串。 我想更改該字符串的文本,當我們單擊該搜索欄時,我們會在搜索欄旁邊看到一個取消按鈕,我想更改該取消按鈕的文本。
使用外觀代理:
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"];
您還需要在程序之前設置“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 出現問題!
適用於 iOS 7 的解決方案。所有功勞都歸功於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];
}
}
如果“搜索字符串”是指占位符,那么應該這樣做:
[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"];
}
}
請注意,取消按鈕是延遲加載的,因此您必須在用戶激活搜索欄時進行此修改。
在 iOS 7 中,如果您使用 UISearchBar 只需在 searchBarTextDidBeginEditing: 方法中編寫此代碼
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];
}
}
我想修復 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]
,它也適用於后退按鈕。
這個解決方案對我有用 - 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];
}
在 iOS 7 上,如果您在UISearchDisplayController
上設置了UISearchDisplayController
displaysSearchBarInNavigationBar = YES
,則通過子視圖遞歸替換取消按鈕標題或外觀代理將不起作用。
相反,在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;
}
Jeremytripp 在 Swift 中的工作代碼
我在 Swift 中找不到相同的代碼,所以我自己“翻譯”了它:
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)
}
}
}
如果您只想本地化取消按鈕的默認“取消”標題,我更喜歡將CFBundleDevelopmentRegion鍵的值從 en 更改為項目中 Info.plist 文件中的本地化區域。
這是我的變化,
<key>CFBundleDevelopmentRegion</key>
<string>zh_CN</string>
之后,默認的“取消”標題將顯示為中文“取消”。 此更改也會影響所有默認區域值,例如 UITextField/UITextView 上粘貼板操作的動作標題將被本地化,“選擇”->“選擇”,“粘貼”->“粘貼”...
順便說一下,Info.plist 文件可以完美地本地化。
享受!
我沒有引用非公共 UINavigationButton 類,而是執行了以下操作。 我希望它能通過 App Store 審核!
for (id subview in searchBar.subviews) {
if ([subview respondsToSelector:@selector(setTitle:)]) {
[subview setTitle:@"Map"];
}
}
如果您仍然無法更改 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];
}
}
如果 SearchBar 在導航欄中,則代碼將與通常的答案不同; 您需要改為搜索 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+ 中工作,如果您仍然無法設置標題,則應該學習視圖調試 - 這就是我解決這個問題的方法。
這個簡短的教程很好地概括了視圖調試的要點:
http://www.raywenderlich.com/98356/view-debugging-in-xcode-6
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 版本
在 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)
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.