如何使用UISearchController添加搜索UITableViews

这是一个有关如何使用新的UISearchController向UITableViews添加搜索功能的简单教程。 UISearchController是几年前在iOS 8中引入的,以取代现在不推荐使用的UISearchDisplayController。 在新的搜索控制器中,将搜索添加到表视图更加容易。 从Xcode 8.1开始,UISearchController尚未添加到Interface Builder,因此您必须以编程方式添加它。 即使如此,使用它还是很容易的。

设置我们的UITableView

在Interface Builder中,将UITableViewController添加到情节提要中。 默认情况下,UITableViewController将使用动态单元格。 这对于我们的演示来说是完美的。 我们需要做的唯一其他配置是配置动态单元。 单击该单元格,并为其提供重用标识符。 我将其标记为“ basicCell”。接下来,将单元格样式设置为“基本”,因为我所需要的只是在单元格中显示文本。

现在我们需要用数据填充表格视图,因此我们需要搜索一些内容。 我目前正在看周一足球比赛,所以我想着足球。 我将所有NFL球队添加到我们的表格视图中。 以下是一些非常基本的UITableView内容。 一个函数指示我们有多少节,另一个函数指示我们有多少行,最后的覆盖为单元格配置数据。 它们都使用数据源unfilteredNFLTeams ,这是我在viewDidLoad函数中填充的数组。

 请参阅完整文章中的代码。 

这就是我们运行演示时的样子。

添加UISearchController

现在我们的表视图已设置好要搜索的数据,下一步是添加一个UISearchController并对其进行配置。 UISearchController的初始化程序可以使用一个参数,该参数可以指定其他视图控制器以显示搜索结果。 我认为最常见的用例是在具有表视图的同一视图控制器中显示搜索结果。 传递nil表示我们不希望其他视图控制器显示搜索结果。

 请参阅完整文章中的代码。 

现在,我们创建了UISearchController,我们需要应用一些设置。 在viewDidLoad函数中,使用以下代码配置UISearchController:

 请参阅完整文章中的代码。 

让我解释一下您刚刚添加的内容:

  1. 我们需要实现UISearchResultsUpdating协议(稍后会详细介绍)。 将searchResultsUpdater属性设置为self,将委托设置为我们的视图控制器实例。
  2. hidesNavigationBarDuringPresentation设置为false可以防止在您键入搜索栏时隐藏导航栏。
  3. dimsBackgroundDuringPresentation指示键入搜索时搜索结果是否看起来暗淡。 我发现这会分散注意力,因此将其设置为false
  4. 最后,我们将表视图的标题视图设置为UISearchController的搜索栏。

实施UISearchResultsUpdating协议

该协议仅包含我们需要实现的一个功能。 对于在搜索栏中键入的每个字符,都会调用updateSearchResults函数。 您需要过滤自己的数据并自己更新表视图。 让我们为NFL球队做到这一点。 这是我对updateSearchResults函数的实现。

 请参阅完整文章中的代码。 

我在视图控制器中引入了第二个变量,以跟踪称为filteredNFLTeams的NFL团队的已过滤列表。 当有人在搜索栏中键入内容时,我需要使用包含这些字符的NFL小组更新过滤后的列表。

if let语句检查searchBar.text是否为nil,还检查文本是否为空字符串。 如果没有搜索文字,则将NFL球队的原始完整列表分配给filteredNFLTeams变量。 否则,我会在NFL球队名单上使用Swift的过滤器功能。 我还将每个字符串都小写以进行不区分大小写的搜索。 最后,我告诉表格视图重新加载其数据。

切换表格视图以使用过滤后的数据集

表格视图需要使用经过过滤的NFL球队数组作为数据源,而不是原始列表。 在viewDidLoad函数中,我将filteredNFLTeams数组初始化为与未过滤列表相同。 接下来,在所有表视图数据源函数中,我都将unfilteredNFLTeams变量替换为已过滤数组。 唯一需要unfilteredNFLTeams数组的时间是根据搜索栏文本过滤列表时。

 请参阅完整文章中的代码。 

现在,我们运行该应用程序时,您会看到搜索栏出现在列表顶部。 键入时,我可以看到表格视图更新。

防止UISearchController过度使用它

如果您的应用程序中有多个场景,您将开始注意到一个问题,即使您导航到应用程序中的其他场景,UISearchController似乎仍会徘徊。 如果您正在使用第二个视图控制器来显示搜索结果,则可能是正确的行为,但是就我而言,当我离开表视图导航时,我希望它消失。 一种建议是在viewDidLoad函数definesPresentationContext = true添加以下代码。 我发现这对我不起作用。 当我导航到下一个场景然后返回到我的NFL列表时,该列表将为空。 另外,搜索栏在某些情况下仍会保留。

我发现更好的解决方案是当我离开时关闭UISearchController。 我实现了viewWillDisappear函数,如下所示:

 请参阅完整文章中的代码。 

希望您发现添加UISearchController并不需要太多工作。 一旦Apple更新了Interface Builder使其包含UISearchController,它的代码就应该更少了。

UISearchController的限制之一是它仅适用于UITableViewControllers。 不支持包含UITableView的常规UIViewControllers。 在我的下一篇博客文章中,我将向您展示如何解决此限制。