
上一篇 開始用Swift開發(fā)iOS 10 - 17 使用Core Data 是使用Core Data存儲數(shù)據(jù),這一篇是添加搜索功能。
使用 UISearchController
UISearchController是一個(gè)簡潔的創(chuàng)建搜索條和管理搜索結(jié)果的API。
通常情況下,為以table為基礎(chǔ)的app添加搜索條只需要下面三行代碼就可以了,searchResultsController為nil時(shí)搜索結(jié)果顯示就在當(dāng)前搜索的頁面以當(dāng)前的樣式顯示。
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
tableView.tableHeaderView = searchController.searchBar

為我的FoodPin應(yīng)用添加搜索條:
-
在
RestaurantTableViewController中添加一個(gè)變量:var searchController: UISearchController! -
在
viewDidLoad中初始化:searchController = UISearchController(searchResultsController: nil) tableView.tableHeaderView = searchController.searchBar
這樣就添加了搜索條,但還每天添加搜索邏輯,搜索沒效。

篩選內(nèi)容
-
在
RestaurantTableViewController中繼續(xù)添加一個(gè)變量,用戶存儲篩選結(jié)果: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是數(shù)組的一個(gè)方法,它遍歷數(shù)組的每一項(xiàng)進(jìn)行閉包中的操作,根據(jù)結(jié)果判斷是否刪除對應(yīng)項(xiàng),最后得到一個(gè)篩選的數(shù)組。
localizedCaseInsensitiveContains方法用來判斷name中是否包含searchText(忽略大小寫)
更新搜索結(jié)果
-
讓
RestaurantTableViewController“符合”UISearchResultsUpdating協(xié)議:class RestaurantTableViewController: UITableViewController, NSFetchedResultsControllerDelegate, UISearchResultsUpdating 實(shí)現(xiàn)
UISearchResultsUpdating協(xié)議:
中的updateSearchResults(for:)方法,這個(gè)方法在搜索條被選則和輸入搜索字時(shí)調(diào)用:
func updateSearchResults(for searchController: UISearchController) {
if let searchText = searchController.searchBar.text {
filterContent(for: searchText)
tableView.reloadData()
}
}
- 更新
tableView(_:numberOfRowsInSection:)。UISearchController有一個(gè)isActive屬性用來判斷搜索控制器當(dāng)前活躍狀態(tài)。
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchController.isActive {
return searchResults.count
} else {
return restaurants.count
}
}
- 更新
tableView(_:cellForRowAt:)。根據(jù)UISearchController的狀態(tài)判斷是從restaurants中獲取數(shù)據(jù)還是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
}
- 實(shí)現(xiàn)一個(gè)新的方法,讓table在搜索狀態(tài)下不可以滑動編輯。
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
if searchController.isActive {
return false
} else {
return true
}
}
-
更新
prepare(for:),讓segue在傳輸數(shù)據(jù)到detail view時(shí)的數(shù)據(jù)也相對應(yīng)。destinationController.restaurant = searchController.isActive ? searchResults[indexPath.row] : restaurants[indexPath.row 在
viewDidLoad中添加兩行代碼:
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
現(xiàn)在就完成了搜索功能。

定制搜索條的樣式
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:添加地址搜索
只需要更改搜索函數(shù)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
說明
此文是學(xué)習(xí)appcode網(wǎng)站出的一本書 《Beginning iOS 10 Programming with Swift》 的一篇記錄
系列文章目錄
- 開始用Swift開發(fā)iOS 10 - 1 前言
- 開始用Swift開發(fā)iOS 10 - 2 Hello World!第一個(gè)Swift APP
- 開始用Swift開發(fā)iOS 10 - 3 介紹Auto Layout
- 開始用Swift開發(fā)iOS 10 - 4 用Stack View設(shè)計(jì)UI
- [開始用Swift開發(fā)iOS 10 - 5 原型的介紹]
- 開始用Swift開發(fā)iOS 10 - 6 創(chuàng)建簡單的Table Based App
- 開始用Swift開發(fā)iOS 10 - 7 定制Table Views
- 開始用Swift開發(fā)iOS 10 - 8 Table View和UIAlertController的交互
- 開始用Swift開發(fā)iOS 10 - 9 Table Row的刪除, UITableViewRowAction和UIActivityViewController的使用
- 開始用Swift開發(fā)iOS 10 - 10 Navigation Controller的介紹和Segue
- 開始用Swift開發(fā)iOS 10 - 11 面向?qū)ο缶幊探榻B
- 開始用Swift開發(fā)iOS 10 - 12 豐富Detail View和定制化Navigation Bar
- 開始用Swift開發(fā)iOS 10 - 13 Self Sizing Cells and Dynamic Type
- 開始用Swift開發(fā)iOS 10 - 14 基礎(chǔ)動畫,模糊效果和Unwind Segue
- 開始用Swift開發(fā)iOS 10 - 15 使用地圖
- 開始用Swift開發(fā)iOS 10 - 16 介紹靜態(tài)Table Views,UIImagePickerController和NSLayoutConstraint
- 開始用Swift開發(fā)iOS 10 - 17 使用Core Data