带有范围过滤器的UISearchController
允许用户筛选您的列表可以改善用户的整体体验。 在这里,我们将学习如何使用现有的表格视图配置UISearchController并应用搜索栏。 因此,让我们直接进入。
入门项目
让我们从以下针对iOS 8及更高版本的入门项目开始。 我在以前的文章中没有使用过Storyboard,所以我决定在这里使用它。 如果您现在运行该应用程序,将会看到一个宠物小精灵的列表,其中包含它们的名称,元素和图像。 我们将要交互的主要文件如下
- Pokemon.swift —包含宠物小精灵的名称,元素和图像的模型类
- PokemonDataSource.swift —包含用于生成口袋妖怪列表的类方法
- ViewController.swift —显示宠物小精灵的列表
配置SearchController
在ViewController.swift中,让我们添加到我们的searchController中。 注意,我们为参数传递了nil。
如果要在显示可搜索内容的同一视图控制器中显示搜索结果,请指定nil。
私人让searchController = UISearchController(searchResultsController:nil)
现在,我们有一个要管理的UISearchController实例,让我们继续进行配置。 在函数configureSearchController()中,添加以下内容
searchController.dimsBackgroundDuringPresentation = false
definePresentationContext = true
tableView.tableHeaderView = searchController.searchBar
通过将dimsBackgroundDuringPresentation设置为false,我们可以通知searchController在激活背景时不要使其背景变暗。 您应该将其设置为yes只是为了第一手看到它。 注意,我们将definePresentationContext设置为true。 这样可以确保,如果我们导航到另一个视图控制器,则搜索栏应仅保留在原始视图控制器中。 您应该看到以下内容; 但是,您会注意到搜索当前无效。 因此,让我们添加此功能!
文字过滤器
我们首先需要遵守UISearchResultsUpdating协议,以利用方法updateSearchResultsForSearchController(:)
每当搜索栏成为第一响应者或对搜索栏中的文本进行更改时,都会自动调用此方法。 在此方法内部执行所有必需的筛选和更新。
现在,我们将扩展ViewController使其符合UISearchResultsUpdating。 在这里,我们将实现此方法并将其调用filterSearchController(:)。 我们将在短期内重用filterSearchController。
func updateSearchResultsForSearchController(searchController:UISearchController)
{
filterSearchController(searchController.searchBar)
}
由于我们将显示已过滤的宠物小精灵的列表,因此我们不想破坏我们的pokemonList数组。 为了保留我们原来的pokemonList,我们将一个filteredPokemonList变量添加到我们的ViewController中。 注意它是可变的,因为它将经常更改。
私人varfilteredPokemonList = [Pokemon]()
在ViewController.swift中,继续并使用以下代码实现filterSearchController(searchBar:UISearchBar)。
让searchText = searchBar.text ?? ”
filteredPokemonList = pokemonList.filter {pokemon in
让isMatchingSearchText = pokemon.name.lowercaseString.containsString(searchText.lowercaseString)|| searchText.lowercaseString.characters.count == 0
返回isMatchingSearchText
}
tableView.reloadData()
我们首先获取searchText并使用Swift的高阶过滤器来过滤我们的pokemonList。 我们确保口袋妖怪的名称包含输入的字符串。 如果searchText为空,则应全部显示。 如果我们不添加第二个条件,那么当searchBar为空时,我们什么也看不到! 这将更新filterPokemonList并因此更新tableview。 但是,等等,我们的tableview如何知道何时使用filteredPokemonList和pokemonList? 只需通过更新cellForRowAtIndexPath(:)和numberOfRowsInSection(:)来说明searchController的活动状态即可。
在cellForRowAtIndexPath中,继续并使用以下一个衬里更新我们的pokemon变量。
让pokemon = searchController.active吗? filteredPokemonList [indexPath.row]:pokemonList [indexPath.row]
? :语法称为三元运算符。 它说,如果searchController是活动的,则使用filteredPokemonList [indexPath.row],否则使用pokemonList [indexPath.row]。 否则,可以将其视为一个衬板。
现在,在numberOfRowsInSection中,我们要确保使用了正确的行数,因此让我们对其进行更新。
返回searchController.active吗? filteredPokemonList.count:pokemonList.count
最后一件事,请确保将searchController的委托设置为self,以便它将在configureSearchController中侦听这些更改。
searchController.searchResultsUpdater =自我
多数民众赞成在基本的文本过滤!
范围过滤器
如果我们可以添加其他级别的过滤,那就太好了。 事实证明,我们可以做到,并且可以使用UISearchBar进行烘焙。 有了这些作用域,我们现在可以按元素进行筛选,例如火,水,草,甚至所有元素。
让我们更新configureSearchController(),以便获得此功能。 添加以下行。
searchController.searchBar.scopeButtonTitles = [“所有”,“草”,“火”,“水”]
您可以运行项目以查看创建的scopeButtonTitles。
再一次,我们将需要遵守协议,以便我们知道何时选择了过滤器范围并应用必要的过滤器。 让我们通过再次扩展ViewController来符合UISearchBarDelegate。 我们将在回调方法selectedScopeButtonIndexDidChange中重用我们的方法filterSearchController,因为我们实际上是在再次过滤。
func searchBar(searchBar:UISearchBar,selectedScopeButtonIndexDidChange selectedScope:Int){
filterSearchController(searchBar)
}
确保在configureSearchController中设置searchBar的委托,以便通知ViewController。
searchBar.delegate =自我
现在,我们应该更新filterSearchController来考虑元素过滤器。
守卫let scopeString = searchBar.scopeButtonTitles?[searchBar.selectedScopeButtonIndex] else {return}
让selectedElement = Pokemon.Element(rawValue:scopeString)?? 。所有
让searchText = searchBar.text ?? ”
//通过元素和文本过滤pokemonList
filteredPokemonList = pokemonList.filter {pokemon in
让isElementMatching =(selectedElement == .All)|| (pokemon.element == selectedElement)
让isMatchingSearchText = pokemon.name.lowercaseString.containsString(searchText.lowercaseString)|| searchText.lowercaseString.characters.count == 0
返回isElementMatching && isMatchingSearchText
}
tableView.reloadData()
请注意已进行的细微更改。 scopeString是通过selectedIndex处的searchBar的buttonTitles获得的。 然后我们创建一个枚举,因为它将是元素类型的四种可能性中的任何一种。 过滤器现在通过快速布尔检查考虑了elementMatching。 现在,如果口袋妖怪的元素与用户的选择匹配,并且searchText匹配,它将被添加到filterList中。
测试
继续进行下去。 现在,您有了具有过滤器和范围过滤器功能的表格视图! 完整的项目在这里。