簡體   English   中英

如何更改出現在 UISearchBar +iPhone 中的取消按鈕的默認文本

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM