我的收藏

【译】使用UISearchController展示搜索内容

2019-03-12  本文已影响0人  luowanglin

翻译:luowanglin
原文地址

概览

这个Demo演示了表视图控制器(UITableViewController)和搜索控制器(UISearchController),怎样去创建一个管理和展示搜索内容的用户交互功能。通过创建一个自定义的表视图控制器,同时这个表示图控制器也充当展示或搜索结果的内容提供器,然后展示搜索内容范围内的过滤结果。

这个Demo实现了可选的UIStateRestoring接口协议,官方推介实现该接口协议。当app重启动时,可以通过视图控制器类去保存搜索栏的活动状态,其中包括第一响应状态和搜索栏文本,可进行数据的恢复。间接提升了更好的用户体验。

override func viewDidLoad() {
    super.viewDidLoad()

    resultsTableController = ResultsTableController()

    resultsTableController.tableView.delegate = self
    
    searchController = UISearchController(searchResultsController: resultsTableController)
    searchController.searchResultsUpdater = self
    searchController.searchBar.autocapitalizationType = .none
    
    if #available(iOS 11.0, *) {
        // For iOS 11 and later, place the search bar in the navigation bar.
        navigationItem.searchController = searchController
        
        // Make the search bar always visible.
        navigationItem.hidesSearchBarWhenScrolling = false
    } else {
        // For iOS 10 and earlier, place the search controller's search bar in the table view's header.
        tableView.tableHeaderView = searchController.searchBar
    }

    searchController.delegate = self
    searchController.dimsBackgroundDuringPresentation = false // The default is true.
    searchController.searchBar.delegate = self // Monitor when the search button is tapped.
    
    /** Search presents a view controller by applying normal view controller presentation semantics.
        This means that the presentation moves up the view controller hierarchy until it finds the root
        view controller or one that defines a presentation context.
    */
    
    /** Specify that this view controller determines how the search controller is presented.
        The search controller should be presented modally and match the physical size of this view controller.
    */
    definesPresentationContext = true
}

创建一个搜索控制器

使用继承至UITableViewController的MainTableViewController类去创建一个搜索控制器。ResultsTableController表视图控制器用于展示搜索栏中过滤后的产品(Product)结果。

为了兼容iOS系统版本,MainTableViewController搜索控制器需要进行系统版本的判断,当系统版本小于或等于iOS10时,你可以通过替换tableview里面的header视图,而在iOS11后的版本,你可以直接替换视图控制器的导航栏(navigation bar)。

刷新搜索结果

这个例子使用了UISearchResultsUpdating协议以及谓语适配器NSComparisonPredicate,去过滤分组里可用的产品(product)搜索结果。谓语(NSComparisonPredicate)是一个正则匹配基类,通过相应谓语查询规则进行查询或过滤。搜索规则是基于搜索栏的使用类型,会结合产品名称、年份以及价格。

通过在裁截输入栏中关键字的开头和结尾预前进行搜索。然后搜索字符串通过NSComparisonPredicate类里的findMatches函数进行搜索结果返回。这个搜索结果以列表的方式返回。

func updateSearchResults(for searchController: UISearchController) {
       // Update the filtered array based on the search text.
       let searchResults = products

       // Strip out all the leading and trailing spaces.
       let whitespaceCharacterSet = CharacterSet.whitespaces
       let strippedString =
           searchController.searchBar.text!.trimmingCharacters(in: whitespaceCharacterSet)
       let searchItems = strippedString.components(separatedBy: " ") as [String]

       // Build all the "AND" expressions for each value in searchString.
       let andMatchPredicates: [NSPredicate] = searchItems.map { searchString in
           findMatches(searchString: searchString)
       }

       // Match up the fields of the Product object.
       let finalCompoundPredicate =
           NSCompoundPredicate(andPredicateWithSubpredicates: andMatchPredicates)

       let filteredResults = searchResults.filter { finalCompoundPredicate.evaluate(with: $0) }

       // Apply the filtered results to the search results table.
       if let resultsController = searchController.searchResultsController as? ResultsTableController {
           resultsController.filteredProducts = filteredResults
           resultsController.tableView.reloadData()
       }
   }

源码下载

上一篇下一篇

猜你喜欢

热点阅读