【问题标题】:iOS Change the title of cancel button in UISearchBariOS 更改 UISearchBar 中取消按钮的标题
【发布时间】:2017-05-03 04:56:04
【问题描述】:

我希望更改 iOS 中取消按钮的标题。我以前一直在使用它:

- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller{
  self.searchDisplayController.searchBar.showsCancelButton = YES;
  UIButton *cancelButton = nil;
  for (UIView *subView in self.searchDisplayController.searchBar.subviews) {
     if ([subView isKindOfClass:NSClassFromString(@"UIButton")]) {
         cancelButton = (UIButton*)subView;
     }
  }
  [cancelButton setTitle:@"Annuller" forState:UIControlStateNormal];
}

但它似乎在 iOS7 中不起作用。有什么建议么?

【问题讨论】:

  • [cancelButton setTitle:@"Annuller" forState:UIControlStateNormal]; 放入 if 条件中。也检查同样的问题Customizing Cancel button of UISearchBar
  • 如果您只想本地化取消按钮的默认“取消”标题,我更喜欢将 CFBundleDevelopmentRegion 键的值从 en 更改为您在项目中 Info.plist 文件中的本地化区域。从这里查看详细答案:stackoverflow.com/a/37427398/1677041

标签: ios uisearchbar


【解决方案1】:

您需要递归搜索按钮。这应该是一种万无一失的方法:

- (void)viewDidLoad
{
    [super viewDidLoad];

    [self convertButtonTitle:@"Cancel" toTitle:@"Annuller" inView:self.searchBar];
}

- (void)convertButtonTitle:(NSString *)from toTitle:(NSString *)to inView:(UIView *)view
{
    if ([view isKindOfClass:[UIButton class]])
    {
        UIButton *button = (UIButton *)view;
        if ([[button titleForState:UIControlStateNormal] isEqualToString:from])
        {
            [button setTitle:to forState:UIControlStateNormal];
        }
    }

    for (UIView *subview in view.subviews)
    {
        [self convertButtonTitle:from toTitle:to inView:subview];
    }
}

我仅在 iOS 7 上对此进行了测试,但它在 iOS 6 上也能正常工作。

【讨论】:

  • 在 6 和 7 上测试。完美运行。非常感谢!
  • 如果可以的话我会,但我没有问过问题,只是想让其他人知道,您的代码有效:)
  • 如果用户使用非英语的任何语言运行 iOS,这将不起作用。
  • 我假设该应用程序仅本地化为英语。如果是这种情况,设备的语言不会影响取消按钮的语言,并且此代码可以正常工作。如果您需要处理本地化的应用程序,请告诉我,我会更新答案:)
  • 此方法适用于iOS7.1,但您需要在viewDidLoad 方法中添加:[self.searchBar setShowsCancelButton:YES]。这种方法可能是个 hack,但 UIAppearance 方法似乎会使 iOS 7.0.x 崩溃(尽管该方法也适用于 iOS 7.1.x)
【解决方案2】:

只需为它执行此代码:-

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar
{
    /* when user start editing in serchbar this method will display cancel button and disable the autocorrection functionality */

    srcbar.showsCancelButton = YES;

    for (UIView *subView in searchBar.subviews) {
        if ([subView isKindOfClass:[UIButton class]]) {
           UIButton *cancelButton = (UIButton*)subView;

            [cancelButton setTitle:@"hi" forState:UIControlStateNormal];
        }
    }
    srcbar.autocorrectionType = UITextAutocorrectionTypeNo;

}

未在 iOS7 中测试,但在 iOS6 中可以正常工作,希望对您有用。

输出是:-

【讨论】:

  • 我已经使用它来更新教程中的代码:ios-blog.co.uk/tutorials/… 并且您已被提及。谢谢
  • 你有没有检查断点searchBarTextDidBeginEditing 是否正在调用?正确检查您是否给了您 SeachBar 的代表? @RameezHussain 因为 OP 说它在 iOS7 中工作
  • 它被调用一次,然后它不会改变外观。
  • [[UIBarButtonItem appearanceWhenContainedIn:[UISearchBar class], nil] setTitle:@"YourNewTextHere"];就用这个iOS 7
  • 我真的不认为遍历所有子视图(私有视图层次结构)以希望找到我们想要的视图(并且希望是我们想要的类)可以修改 - 这种解决方案可能暂时有效,但如果 Apple 改变了他们的视图层次结构(这是不可能的),那么你将留下一个损坏的应用程序。
【解决方案3】:

这是我对 ios6 和 ios7 的解决方案

#define IS_IOS7 (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)
- (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller
{
    self.searchDisplayController.searchBar.showsCancelButton = YES;

    UISearchBar *searchBar = self.searchDisplayController.searchBar;
    UIView *viewTop = IS_IOS7 ? searchBar.subviews[0] : searchBar;
    NSString *classString = IS_IOS7 ? @"UINavigationButton" : @"UIButton";

    for (UIView *subView in viewTop.subviews) {
        if ([subView isKindOfClass:NSClassFromString(classString)]) {
            UIButton *cancelButton = (UIButton*)subView;
            [cancelButton setTitle:@"your title" forState:UIControlStateNormal];
        }
    }
}

【讨论】:

    【解决方案4】:

    为了让它在iOS7上运行,你必须在搜索栏的子视图中搜索:

    //iOS 7 hack
    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:@"Anuluj" forState:UIControlStateNormal];
        }
    }
    

    【讨论】:

      【解决方案5】:

      将这一行放在 appDelegate 中

      [[UIButton appearanceWhenContainedIn:[UISearchBar class], nil] setTitle:@"Your Title" forState:UIControlStateNormal];

      【讨论】:

      • 或使用 iOS 9 和 Swift:UIButton.appearanceWhenContainedInInstancesOfClasses([UISearchBar.self]).setTitle("Your Title", forState: .Normal)
      【解决方案6】:

      对于 Swift 3.0

      这工作正常。

      func setSearchButtonText(text:String,searchBar:UISearchBar) {
      
          for subview in searchBar.subviews {
              for innerSubViews in subview.subviews {
                  if let cancelButton = innerSubViews as? UIButton {
                      cancelButton.setTitleColor(UIColor.white, for: .normal)
                      cancelButton.setTitle(text, for: .normal)
                  }
              }
          }
      
      }
      

      并调用方法

      setSearchButtonText(text: "Done", searchBar: yourSearchBar)
      

      这是输出

      【讨论】:

        【解决方案7】:

        如果您只想在您的语言环境中将“取消”文本更改为相同,我认为正确的方法是使用本地化。方法如下:

        1. 在 Finder 中打开您的项目,找到 en.lproj 目录
        2. 将其重命名为您的语言环境,或者如果您必须支持多种语言,则复制它
        3. 删除它可能包含在 Xcode 中的所有文件引用(它们应该看起来是红色的)
        4. 将 Finder 中的相同文件从新目录拖到 Xcode 中
        5. (不确定是否有必要)编辑您的 Info.plist 并添加以下行:

          • Localization native development region:您所在的地区(例如:en
          • Localizations:例如English

        注意:不能在模拟器中使用,请在设备上测试!

        (来源:http://www.ibabbleon.com/iphone_app_localization.html

        【讨论】:

          【解决方案8】:

          @Nitin Gohel 喜欢吗?

          - (void)searchDisplayControllerWillBeginSearch:(UISearchDisplayController *)controller{
            self.searchDisplayController.searchBar.showsCancelButton = YES;
            UIButton *cancelButton = nil;
            for (UIView *subView in self.searchDisplayController.searchBar.subviews) {
               if ([subView isKindOfClass:NSClassFromString(@"UIButton")]) {
                   cancelButton = (UIButton*)subView;
          
                   [cancelButton setTitle:@"Annuller" forState:UIControlStateNormal];
               }
           }
          
          }
          

          【讨论】:

          • 这非常有效。也许,坏事是我看到取消按钮的 TextColor 正在更改。我试图重新申请 [cancelButton setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; ,它不起作用,我也看到它采用 Search Bar BarTint 的颜色而不是 SearchBar Tint 颜色。
          【解决方案9】:

          似乎“self.searchDisplayController.searchBar.subviews”只是返回“searchBar”本身。我尝试了以下方法,它有效!

          for (UIView *searBarView in [self.searchDisplayController.searchBar subviews])
          {
              for (UIView *subView in [searBarView subviews]) 
              {
                  if ([subView isKindOfClass:[UIButton class]])
                  {
                      UIButton *cancleButton = (UIButton *)subView;
                      [cancleButton setTitle:@"hi" forState:UIControlStateNormal];
                  }
              }
          
          }
          

          【讨论】:

            【解决方案10】:

            在搜索开始之前,在 UISearchBarDelagate 或 UISearchDisplayControllerDelegate 中做:

            [self.searchDisplayController.searchBar.subviews enumerateObjectsUsingBlock:^(UIButton *subview, NSUInteger idx, BOOL *stop) {
                        if ([subview isKindOfClass:[UIButton class]]) {
                            [subview setTitle:@"OK" forState:UIControlStateNormal];
                            *stop = YES;
                        }
                    }];
            

            【讨论】:

              【解决方案11】:

              对于 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:@"YourTitle" forState:UIControlStateNormal];
                  }
              }
              

              【讨论】:

                【解决方案12】:

                参考上面@Salih 的解决方案,我使用了这段代码并且工作完美!应用启动时只需调用 AppDelegate.m 中的 setupAppearance 方法即可。

                - (void)setupAppearance
                {
                   id appearance = nil;
                
                   if (IOS9_OR_LATER) {
                       appearance = [UIBarButtonItem appearanceWhenContainedInInstancesOfClasses:@[[UISearchBar class]]];
                   } else {
                       appearance = [UIBarButtonItem appearanceWhenContainedIn:[UISearchBar class], nil];
                   }
                
                   [appearance setTitle:@"CANCEL"];
                }
                

                【讨论】:

                  【解决方案13】:

                  加入我在UIKitUISearchResultsUpdating协议方法updateSearchResults(for searchController: UISearchController)中使用的代码:

                  if let cancelButton : UIButton = searchController.searchBar.value(forKey: "_cancelButton") as? UIButton {
                      cancelButton.setTitle("Back", for: UIControlState.normal)
                  }
                  

                  (iOS 10,Swift 3.0)

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-10-10
                    • 1970-01-01
                    相关资源
                    最近更新 更多