1. 使用UISearchController来创建搜索条
说明:在TableView的使用的基础上进行
(1)添加搜索条到TableView的关键代码
//1. 定义搜索控制器变量UISearchController
var sc : UISearchController!
//2.UISearchController初始化
//实例化结果:搜索结果控制器(nil则结果显示在搜索条所在视图)
sc = UISearchController(searchResultsController: nil)
//更新搜索结果的控制器
sc.searchResultsUpdater = self
//将TableView的页眉视图定义为搜索条
tableView.tableHeaderView = sc.searchBar
(2)遵从searchResultsUpdater代理相关的协议UISearchResultsUpdating
备注:遵从UISearchResultsUpdating协议并实现updateSearchResults方法,当点击搜索条或者更改搜索文字时调用updateSearchResults方法,让搜索控制器显示搜索结果.
func updateSearchResults(for searchController: UISearchController) {
}
(3)运行结果
2. 筛选内容
筛选器:搜索控制器没有现成的搜索功能,需要手动添加筛选规则
var searchResults : [MyDevice] = []//定义空数组保存筛选结果
//添加一个筛选器方法:使用Swift数组自带filter方法,返回一个符合条件的新数组
func searchFilter(text:String) {
searchResults = devices.filter({ (area) -> Bool in
return area.deviceName.localizedCaseInsensitiveContains(text)
})
}
3. 更新筛选结果(实现updateSearchResults方法)
实现updateSearchResults方法,当点击搜索条或者更改搜索文字时调用updateSearchResults方法,让搜索控制器显示搜索结果.
//当点击搜索条或者更改搜索文字时被调用
func updateSearchResults(for searchController: UISearchController) {
//获取搜索栏文字,筛选后刷新列表
if let text = searchController.searchBar.text {
searchFilter(text: text)
tableView.reloadData()
}
}
4. 显示筛选结果
原数据源和搜索结果(新数据源)的区分,即何时显示搜索结果并更新列表的数据源:当搜索条在使用时,isActive属性为true,搜索结果为新的数据源.
备注:搜索时单元格不可编辑
5. 完整代码
//
// MyTableViewController.swift
// JackUChat
//
// Created by 徐云 on 2019/1/4.
// Copyright © 2019 Liy. All rights reserved.
//
import UIKit
class MyTableViewController: UITableViewController,UISearchResultsUpdating {
var devices = [MyDevice(deviceId: "001", deviceName: "平缝机", deviceCount: "20"),MyDevice(deviceId: "002", deviceName: "包缝机", deviceCount: "20"),MyDevice(deviceId: "003", deviceName: "绷缝机", deviceCount: "20"),MyDevice(deviceId: "004", deviceName: "特种机", deviceCount: "20"),MyDevice(deviceId: "005", deviceName: "裁床", deviceCount: "20"),MyDevice(deviceId: "006", deviceName: "绣花机", deviceCount: "20"),MyDevice(deviceId: "007", deviceName: "abB", deviceCount: "20"),MyDevice(deviceId: "008", deviceName: "aas", deviceCount: "20"),MyDevice(deviceId: "009", deviceName: "AAa", deviceCount: "20"),MyDevice(deviceId: "010", deviceName: "BS", deviceCount: "20"),MyDevice(deviceId: "011", deviceName: "bd", deviceCount: "20"),MyDevice(deviceId: "012", deviceName: "c", deviceCount: "20")]
var sc : UISearchController!//1. 定义UISearchController
var searchResults : [MyDevice] = []//定义空数组保存筛选结果
override func viewDidLoad() {
super.viewDidLoad()
//2.UISearchController初始化
sc = UISearchController(searchResultsController: nil)//结果控制器
sc.searchResultsUpdater = self
tableView.tableHeaderView = sc.searchBar
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.rightBarButtonItem = self.editButtonItem
}
// MARK: - Table view data source
// override func numberOfSections(in tableView: UITableView) -> Int {
// // #warning Incomplete implementation, return the number of sections
// return 0
// }
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
//return devices.count
return sc.isActive ? searchResults.count : devices.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Configure the cell...
let cellId = String(describing: MyTableViewCell.self)
let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! MyTableViewCell
//let device = devices[indexPath.row]
let device = sc.isActive ? searchResults[indexPath.row] : devices[indexPath.row]
cell.deviceNameLabel.text = device.deviceName
cell.deviceNoLabel.text = device.deviceId
cell.countLabel.text = device.deviceCount
return cell
}
//当点击搜索条或者更改搜索文字时被调用
func updateSearchResults(for searchController: UISearchController) {
//获取搜索栏文字,筛选后刷新列表
if var text = searchController.searchBar.text {
text = text.trimmingCharacters(in: .whitespaces)//忽略前后空格
searchFilter(text: text)
tableView.reloadData()
}
}
//添加一个筛选器方法:使用Swift数组自带filter方法,返回一个符合条件的新数组
func searchFilter(text:String) {
searchResults = devices.filter({ (area) -> Bool in
return area.deviceName.localizedCaseInsensitiveContains(text)
})
}
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
//return true
return !sc.isActive
}
/*
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
tableView.deleteRows(at: [indexPath], with: .fade)
} else if editingStyle == .insert {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
*/
/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {
}
*/
/*
// Override to support conditional rearranging of the table view.
override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the item to be re-orderable.
return true
}
*/
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
6.界面展示
7. 定制搜索条外观
(1)外观选项
(2)定制搜索条外观
备注:设置搜索条背景不变暗:默认会变暗,当变暗时不能点击搜索到条目
(3)界面展示
8. 问题汇总:
(1) 搜索条消失的bug:点搜索条展示动画后,搜索条可能被顶到导航栏之上,且不可见
-
原因:取消了导航栏的半透明属性造成的
-
解决:导航控制器的扩展边缘属性,包含不透明条
或者:
self.navigationController?.extendedLayoutIncludesOpaqueBars = true