UISearchController:即使搜索栏为空,也显示结果

opt*_*mus 31 iphone ios ios8 uisearchcontroller

据我了解,默认行为UISearchController是:

  1. 在点击搜索栏时,背景变暗,并显示"取消"按钮.SearchResultsController直到这一点才显示.
  2. SearchResultsController 仅在搜索栏不为空时显示.

我想显示SearchResultsController甚至当搜索栏为空但是被选中时(即上面的情况1).

简单地说,我想显示搜索结果,而不是背景调光.

有没有办法做到这一点?

更多澄清:

我不是UISearchController用来过滤显示它的视图上显示的结果,而是用于其他一些不相关的结果.这就像facebook在其"新闻Feed"中所做的那样.点击搜索栏最初会显示搜索建议,然后,当我们开始编辑时,它会显示可能与新闻Feed无关的搜索结果.

Ken*_*Toh 32

您可以简单地实现UISearchResultsUpdating协议并将结果控制器视图设置为始终显示在updateSearchResultsForSearchController:

 func updateSearchResultsForSearchController(searchController: UISearchController) {

   // Always show the search result controller
   searchController.searchResultsController?.view.hidden = false

   // Update your search results data and reload data
   ..
}
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为即使激活搜索栏而没有任何文本,也会调用该方法.

  • 这对我有用,而且比其他建议的方法简单. (3认同)

小智 31

如果您的searchBar处于活动状态但没有文本,则会显示基础tableView结果.这是内置行为,以及为该状态隐藏searchResultsController的原因.

要在搜索处于活动状态但不进行过滤时更改行为,您必须在通常仍处于隐藏状态时显示searchResultsController.

通过<UISearchResultsUpdating>和可能有一个很好的方法来实现这一目标updateSearchResultsForSearchController:.如果您可以通过协议解决它,那么这是首选方式.

如果这没有帮助,你就会被黑客攻击内置行为.我不会推荐或依赖它,它会变得脆弱,但如果你选择这个选项,这是一个答案:

  1. 确保tableViewController符合<UISearchControllerDelegate>并添加

    self.searchController.delegate = self;

  2. 实行 willPresentSearchController:

    - (void)willPresentSearchController:(UISearchController *)searchController
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            searchController.searchResultsController.view.hidden = NO;
        });
    }
    
    Run Code Online (Sandbox Code Playgroud)

    这使得searchResultsController在将其UISearchController设置为隐藏后可见.

  3. 实行 didPresentSearchController:

    - (void)didPresentSearchController:(UISearchController *)searchController
    {
        searchController.searchResultsController.view.hidden = NO;
    }
    
    Run Code Online (Sandbox Code Playgroud)

有关解决内置行为的更好方法,请参阅malhal的答案.

  • 为了添加答案,我还在`updateSearchResultsForSearchController`委托方法上设置了`view.hidden = false`,以便即使用户清除搜索文本也能保持结果视图控制器可见. (2认同)

mas*_*hix 14

我已经尝试过PetahChristian解决方案,当我们第一次关注搜索栏时,预加载结果显示出来,但是当我们输入内容然后清除它时,预加载结果将不再出现.

我提出了另一个解决方案.我们只需要在SearchResultsController中添加一个委托,并在我们的searchController.searchBar.text为空时调用它.像这样的东西:

SearchResultsController:

protocol SearchResultsViewControllerDelegate {
   func reassureShowingList() -> Void
}

class FullSearchResultsViewController: UIViewController, UISearchResultsUpdating{
   var delegate: SearchResultsViewControllerDelegate?
   ...
   func updateSearchResultsForSearchController(searchController: UISearchController) {
    let query = searchController.searchBar.text?.trim()
    if query == nil || query!.isEmpty {
        ...
        self.delegate?.reassureShowingList()
        ...
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

并且在控制器中包含SearchController,我们添加了委托:

self.searchResultsController.delegate = self
func reassureShowingList() {
    searchController.searchResultsController!.view.hidden = false
}
Run Code Online (Sandbox Code Playgroud)


Sim*_*ang 12

针对 iOS 13 更新

从 iOS13 开始,我们获得了对此行为的系统 API 支持。你可以设置属性showsSearchResultsController = true

世界开发者大会截图

对于 iOS 12 及以下

我最近在工作UISearchController。我想在searchResultsController搜索栏为空时显示搜索历史。因此searchResultsController,无论何时出现,都需要UISearchController出现。

在这里,我使用另一种解决方案searchResultsController通过覆盖hidden自定义视图中的属性来使始终可见。

例如,我的searchResultsController是一个UITableViewController. 我创建了一个VisibleTableView作为 的子类UITableView,然后在 xib 或故事板中将的UITableView自定义类更改searchResultsControllerVisibleTableView。这样,我的searchResultsController永远不会被隐藏UISearchController

这里的好东西:

  1. 比 KVO 更容易实现。

  2. 没有延迟显示searchResultsController。翻转“updateSearchResults”委托方法中的隐藏标志有效,但显示searchResultsController.

  3. 它不会重置隐藏标志,因此隐藏和可见之间没有 UI 间隙/跳跃。

Swift 3 示例代码

class VisibleTableView: UITableView {
override var isHidden: Bool {
    get {
        return false
    }
    set {
        // ignoring any settings
    }
}
}
Run Code Online (Sandbox Code Playgroud)


mal*_*hal 11

有了这样棘手的事情,我推荐大锤方法!那是为了检测何时某些东西试图将其隐藏起来以及何时隐藏它,将其更改回来.这可以通过KVO(键值观察)来完成.无论如何都可以使用,无需处理搜索栏的所有复杂性.对不起,代码很复杂,但KVO是一种较旧的API,但我的代码遵循推荐的做法.在你的SearchResultsViewController中放这个:

static int kHidden;

@implementation SearchResultsViewController

-(void)viewDidLoad{
    [super viewDidLoad];
    [self.view addObserver:self
                   forKeyPath:@"hidden"
                      options:(NSKeyValueObservingOptionNew |
                               NSKeyValueObservingOptionOld)
                      context:&kHidden];
}

- (void)observeValueForKeyPath:(NSString *)keyPath
                      ofObject:(id)object
                        change:(NSDictionary *)change
                       context:(void *)context {
    // if it was our observation
    if(context == &kHidden){
        // if the view is hidden then make it visible.
        if([[change objectForKey:NSKeyValueChangeNewKey] boolValue]){
            self.view.hidden = NO;
        }
    }
    else{
        // if necessary, pass the method up the subclass hierarchy.
        if([super respondsToSelector:@selector(observeValueForKeyPath:ofObject:change:context:)]){
            [super observeValueForKeyPath:keyPath
                                 ofObject:object
                                   change:change
                                  context:context];
        }
    }
}

- (void)dealloc
{
    [self.view removeObserver:self forKeyPath:@"hidden"];
}

// Here have the rest of your code for the search results table.

@end
Run Code Online (Sandbox Code Playgroud)

这适用于所有情况,包括文本是否被清除.

最后,为了防止表格在搜索激活时将丑陋的淡入淡出变为灰色然后变为白色,请使用以下命令:

self.searchController.dimsBackgroundDuringPresentation = NO;
Run Code Online (Sandbox Code Playgroud)


小智 7

Swift 3版本:

如果您searchResultController不是nil并且您使用单独的表视图控制器来显示搜索结果,那么您可以使该表视图控制器符合UISearchResultUpdating并且在该updateSearchResults函数中,您可以简单地取消隐藏视图.

func updateSearchResults(for searchController: UISearchController) {
    view.hidden = false
}
Run Code Online (Sandbox Code Playgroud)

Swift 4版本:

func updateSearchResults(for searchController: UISearchController) {
    view.isHidden = false
}
Run Code Online (Sandbox Code Playgroud)


mat*_*att 5

隐藏的是搜索结果控制器的视图。因此,在它可能被隐藏的任何时候取消隐藏它就足够了。只需在搜索结果控制器中执行以下操作:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    self.view.isHidden = false
}

func updateSearchResults(for searchController: UISearchController) {
    self.view.isHidden = false
    // ... your other code goes here ...
}
Run Code Online (Sandbox Code Playgroud)

现在结果视图(即表格视图)始终可见,即使搜索栏文本为空。

顺便说一下,iOS 邮件应用程序的行为是这样的,我假设它是这样实现的(除非 Apple 可以访问一些秘密的私有 UISearchController 设置)。

[在 iOS 10 和 iOS 11 中测试;我没有在任何早期的系统上进行测试。]