美文网首页ios开发学习小斑ios开发进阶
开始用Swift开发iOS 10 - 18 Search Bar

开始用Swift开发iOS 10 - 18 Search Bar

作者: Andy_Ron | 来源:发表于2017-07-30 15:31 被阅读415次

    上一篇 开始用Swift开发iOS 10 - 17 使用Core Data 是使用Core Data存储数据,这一篇是添加搜索功能。

    使用 UISearchController

    UISearchController是一个简洁的创建搜索条和管理搜索结果的API。
    通常情况下,为以table为基础的app添加搜索条只需要下面三行代码就可以了,searchResultsControllernil时搜索结果显示就在当前搜索的页面以当前的样式显示。

    searchController = UISearchController(searchResultsController: nil)
    searchController.searchResultsUpdater = self
    tableView.tableHeaderView = searchController.searchBar
    

    为我的FoodPin应用添加搜索条:

    • RestaurantTableViewController中添加一个变量:

       var searchController: UISearchController!
      
    • viewDidLoad中初始化:

        searchController = UISearchController(searchResultsController: nil)
        tableView.tableHeaderView = searchController.searchBar
      

    这样就添加了搜索条,但还每天添加搜索逻辑,搜索没效。

    筛选内容

    • RestaurantTableViewController中继续添加一个变量,用户存储筛选结果:

      var searchResults: [RestaurantMO] = []
      
    • 添加筛选方法:

        func filterContent(for searchText: String) {
            searchResults = restaurants.filter({
            (restaurant) -> Bool in
                
                if let name = restaurant.name {
                    let isMatch = name.localizedCaseInsensitiveContains(searchText)
                    return isMatch
                }
                return false
            })
        }
      

    filter是数组的一个方法,它遍历数组的每一项进行闭包中的操作,根据结果判断是否删除对应项,最后得到一个筛选的数组。
    localizedCaseInsensitiveContains方法用来判断name中是否包含searchText(忽略大小写)

    更新搜索结果

    • RestaurantTableViewController “符合” UISearchResultsUpdating协议:

      class RestaurantTableViewController: UITableViewController, NSFetchedResultsControllerDelegate, UISearchResultsUpdating
      
    • 实现UISearchResultsUpdating协议:
      中的updateSearchResults(for:)方法,这个方法在搜索条被选则和输入搜索字时调用:

        func updateSearchResults(for searchController: UISearchController) {
            if let searchText = searchController.searchBar.text {
                filterContent(for: searchText)
                tableView.reloadData()
            }
        }
    
    • 更新tableView(_:numberOfRowsInSection:)UISearchController有一个isActive属性用来判断搜索控制器当前活跃状态。
        override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            if searchController.isActive {
                return searchResults.count
            } else {
                return restaurants.count
            }
        }
    
    • 更新tableView(_:cellForRowAt:)。根据UISearchController的状态判断是从restaurants中获取数据还是searchResults
        override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
            let cellIdentifier = "Cell"
            let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier,
                                                     for: indexPath) as! RestaurantTableViewCell
            
            let restaurant = (searchController.isActive) ? searchResults[indexPath.row] : restaurants[indexPath.row]
            
            cell.nameLabel.text = restaurant.name
            cell.thumbnailImageView.image = UIImage(data: restaurant.image! as Data)
            cell.thumbnailImageView.layer.cornerRadius = 30.0
            cell.thumbnailImageView.clipsToBounds = true
            cell.locationLabel.text = restaurant.location
            cell.typeLabel.text = restaurant.type
            cell.accessoryType = restaurant.isVisited ? .checkmark: .none
            
            return cell
        }
    
    • 实现一个新的方法,让table在搜索状态下不可以滑动编辑。
        override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
            if searchController.isActive {
                return false
            } else {
                return true
            }
        }
    
    • 更新prepare(for:),让segue在传输数据到detail view时的数据也相对应。

        destinationController.restaurant = searchController.isActive ? searchResults[indexPath.row] : restaurants[indexPath.row
      
    • viewDidLoad中添加两行代码:

    searchController.searchResultsUpdater = self
    searchController.dimsBackgroundDuringPresentation = false
    

    现在就完成了搜索功能。

    定制搜索条的样式

    UISearchBar提供一些属性用来定制。在viewDidLoad中添加:

    searchController.searchBar.placeholder = "Search restaurants..."
    searchController.searchBar.tintColor = UIColor.white
    searchController.searchBar.barTintColor = UIColor(red: 218.0/255.0, green:
    100.0/255.0, blue: 70.0/255.0, alpha: 1.0)
    

    Exercise:添加地址搜索

    只需要更改搜索函数filterContent

    searchResults = restaurants.filter({
            (restaurant) -> Bool in
                
                if let name = restaurant.name, let location = restaurant.location {
                    let isMatchName = name.localizedCaseInsensitiveContains(searchText)
                    let isMatchLocation = location.localizedCaseInsensitiveContains(searchText)
                    if isMatchName || isMatchLocation {
                        return true
                    }
                    
                }
                return false
            })
    

    代码

    Beginning-iOS-Programming-with-Swift

    说明

    此文是学习appcode网站出的一本书 《Beginning iOS 10 Programming with Swift》 的一篇记录

    系列文章目录

    相关文章

      网友评论

      • b240f7376923:好像用leancloud这种网络云存储的时候,搜索的写法不太一样是吗
        b240f7376923:@Andy_Ron :smile: 希望有机会您用一下看看,我现在就是卡在搜索这个地方了,他的文档都是OC
        Andy_Ron:@callen_4ac3 是吗!这个我还没用过:smile:

      本文标题:开始用Swift开发iOS 10 - 18 Search Bar

      本文链接:https://www.haomeiwen.com/subject/utznkxtx.html