UINavigationBar/UINavigationItem 中的 UISearchBar 范围按钮

UISearchBar scope buttons in UINavigationBar/UINavigationItem

我正在尝试将 UISearchBar 添加到我的 UINavigationItem,但范围栏显示在搜索栏后面。有解决该问题的想法吗?

iOS: 11.2 xCode: 9.2

我的代码:

- (void)viewDidLoad 
{
    [super viewDidLoad];

    self.mySearchBar = [[UISearchBar alloc] init];
    self.mySearchBar.delegate = self;
    self.mySearchBar.scopeButtonTitles = @[@"item 1", @"item 2", @"item 3"];
    self.navigationItem.titleView = self.mySearchBar;
}

- (BOOL)searchBarShouldBeginEditing:(UISearchBar *)searchBar
{
    [self.mySearchBar setShowsScopeBar: TRUE];
    [self.mySearchBar setShowsCancelButton:TRUE animated:TRUE]; 
    return TRUE;
}   

结果:

上下文

问题是 UINavigationBar 提供了一种非常具体且熟悉的 iOS 样式,Apple 希望在所有应用程序中保持相同的样式。默认导航栏不会展开以适应其内容。

当您设置导航项的 titleView 时,您应该根据导航栏的大小在该视图中布置内容,而不是相反。

解决方案

有几种可能的解决方案:

    UINavigationBar 实例的
  1. Change the behavior(不推荐)。
  2. UISearchBar 作为常规子视图放在导航栏下方。
  3. 使用UISearchController

第一个选项绝对不是您的第一个解决方案,因为它需要您解决许多个棘手的问题。万不得已时使用。

选项 2 需要更改以下代码。将 self.navigationItem.titleView = self.mySearchBar 替换为:

[self.view addSubview:self.mySearchBar];
UILayoutGuide *guide = self.view.safeAreaLayoutGuide;
[self.mySearchBar.topAnchor constraintEqualToAnchor:guide.topAnchor].active = YES;
[self.mySearchBar.rightAnchor constraintEqualToAnchor:guide.rightAnchor].active = YES;
[self.mySearchBar.leftAnchor constraintEqualToAnchor:guide.leftAnchor].active = YES;

并且您还缺少在显示范围栏后调整 UISearchBar 大小的代码。视图不会自行调整大小。因此,在您的 searchBarShouldBeginEditing: 方法中,在 return 之前添加此行: [self.mySearchBar sizeToFit];

第三种解决方案可能对您来说更容易,具体取决于您的用例。也就是说,使用 UISearchController,其中包括锚定在屏幕顶部的自己的 UISearchBar。它看起来就像上面的解决方案#2,如下图所示:

Here is a great tutorial 如果您有兴趣,请使用 UISearchController