【问题标题】:Adding button to left of UISearchBar在 UISearchBar 左侧添加按钮
【发布时间】:2019-08-06 15:06:23
【问题描述】:

我正在为这件事情扯头发。我的客户想在搜索栏的左侧添加一个按钮,如下例所示:


(来源:erik.co.uk

但我就是不知道该怎么做。 Apple 似乎没有提供任何记录在案的方法来将自定义按钮添加到 UISearchBar,更不用说在搜索栏的左侧了。

我尝试在 Interface Builder 中四处乱窜,在左侧添加一个带有按钮的 UIToolbar,但我找不到任何样式组合使两者正确排列以给人一种它们是一体的印象。如下图所示,在垂直对齐中总是有一个像素的差异:


(来源:erik.co.uk

我四处寻找,只是找不到答案,但从截图中我们可以看出,这一定是可能的!

提前感谢您的帮助。

埃里克

【问题讨论】:

标签: iphone uisearchbar


【解决方案1】:

使用导航栏而不是工具栏。将搜索栏设置为导航栏的标题视图。

Interface Builder:

结果:

【讨论】:

  • 感谢 KennyTM,一个完美的答案!做我想做的事!
  • 你的照片已经死了。你能恢复吗?
  • 您能否详细说明您对“使用导航栏而不是工具栏”的回答...我一直在尝试在搜索栏左侧添加一个按钮,但到目前为止没有成功并且不能似乎在谷歌中找到了任何帮助。我应该在 IB 的导航栏上创建 UISearchBar 还是编程?请添加一些示例代码,我会非常喜欢它!!!!!!
  • @ErikCarlson 不要忘记将此标记为正确答案 ;)
  • 这似乎不适用于自动布局。 “执行-layoutSubviews后仍需要Auto Layout。UINavigationBar的-layoutSubviews实现需要调用super。”
【解决方案2】:

您可以替换书签图像,并在必要时调整其偏移量。
例如:

[self.searchDisplayController.searchBar setImage:[UIImage imageNamed:@"plus2"] forSearchBarIcon:UISearchBarIconBookmark state:UIControlStateNormal];
[self.searchDisplayController.searchBar setPositionAdjustment:UIOffsetMake(-10, 0) forSearchBarIcon:UISearchBarIconBookmark];

在委托方法中处理按钮事件:

- (void)searchBarBookmarkButtonClicked:(UISearchBar *)searchBar

看起来是这样的:

【讨论】:

    【解决方案3】:

    第一个解决方案是使用 UINavigationBar 而不是 UIToolbar,正如 KennyTM 注意到的那样。但是您可能对导航栏不满意,例如在我的情况下,当我需要使用 3 个按钮时(导航栏只允许使用 2 个按钮) - 见左图。我就是这样做的:

    1. 在应该放置搜索栏的位置使用Toolbar 和三个按钮,Flexible Space Bar Button Item
    2. 将搜索栏放在(不在)工具栏上。要在Interface Builder 中执行此操作,请不要将搜索栏拖放到工具栏上。相反,请将其放在附近的某个位置,然后使用键盘上的箭头键(或通过更改 Interface Builder 中的 X 和 Y 位置)将其移动到合适的位置。
    3. 搜索栏左下方有黑线(见右图)。为了隐藏它,我添加了一个高度为 1px 并在其上覆盖白色背景的视图。

    对我来说看起来有点脏,所以如果你有更好的解决方案,请告诉我。

    【讨论】:

    • +1 简单干净。在 UIToolbar 中嵌入您的按钮和搜索栏。
    【解决方案4】:

    最简单的解决方案是将你的 SearchBar 添加到 Toolbar 的 TOP 中,(不在),我给你我在我公司 eBuildy 中使用的最佳解决方案:

    UIBarButtonItem *mySettingsButton = [[UIBarButtonItem alloc] initWithTitle:@"Settings" style:UIBarButtonItemStyleBordered target:self action:@selector(refresh)];
    UIBarButtonItem *mySpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
    UIBarButtonItem *myRefreshButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(refresh)];
    UIToolbar *myTopToolbar = [[UIToolbar alloc]initWithFrame:CGRectMake(0,0,320,40)];
    UISearchBar *mySearchBar = [[UISearchBar alloc]initWithFrame:CGRectMake(70,1,220,40)];
    
    [myTopToolbar setItems:[NSArray arrayWithObjects:mySettingsButton,mySpacer,myRefreshButton, nil] animated:NO];
    [self.view addSubview:myTopToolbar];
    [self.view addSubview:mySearchBar];
    

    【讨论】:

      【解决方案5】:

      在这里回答一个老问题,但我最近自己也在努力解决这个问题,并发现其他答案对于我试图解决的情况存在一些缺点。这是我在 UISearchBar 的子类中所做的:

      首先添加一个 UIButton 属性(这里是“selectButton”)。然后重写 initWithFrame 方法并执行类似于以下的操作:

      -(id)initWithFrame:(CGRect)frame{
      if (self = [super initWithFrame:frame])
      {
          self.selectButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
          self.selectButton.contentEdgeInsets = (UIEdgeInsets){.left=4,.right=4};
          [self.selectButton addTarget:self action:@selector(pressedButton:) forControlEvents:UIControlEventTouchUpInside];
      
          self.selectButton.titleLabel.numberOfLines = 1;
          self.selectButton.titleLabel.adjustsFontSizeToFitWidth = YES;
          self.selectButton.titleLabel.lineBreakMode = UILineBreakModeClip;
      
          [self addSubview:self.selectButton];
          [self.selectButton setFrame:CGRectMake(5, 6, 60, 31)];
      }
      
      return self;
      }
      

      现在您要覆盖布局子视图方法以将搜索栏调整为适当的宽度,具体取决于取消按钮是否显示。应该是这样的:

      -(void)layoutSubviews
      {
      [super layoutSubviews];
      
      float cancelButtonWidth = 65.0;
      UITextField *searchField = [self.subviews objectAtIndex:1];
      
      if (self.showsCancelButton == YES)
          [searchField setFrame:CGRectMake(70, 6, self.frame.size.width - 70 - cancelButtonWidth, 31)];
      else
          [searchField setFrame:CGRectMake(70, 6, self.frame.size.width - 70, 31)];
      }
      

      请注意,在上述方法中,我为 cancelButtonWidth 添加了一个常量。我尝试添加代码以从 [self cancelButton] 获取宽度,但这似乎只能在运行时访问并且不允许项目编译。无论如何,这应该是您需要的一个好的开始

      【讨论】:

        【解决方案6】:

        如果您想在右侧使用自定义按钮来代替 Cancel 按钮,只需使用以下代码(适用于 iOS 9 及更高版本):

        [self.searchBar setShowsCancelButton:YES];
        [[UIBarButtonItem appearanceWhenContainedIn:[self.searchBar class], nil] setTitle:@""];
        [[UIBarButtonItem appearanceWhenContainedIn:[self.searchBar class], nil] setImage:[UIImage imageNamed:@"search"]];
        

        【讨论】: