UISearchController是IOS系统提供的搜索相关的综合类,继承搜索查找更新结果与一体,结合UITabView等类似展示工具的时时更新,再好不过,比Android要方便多了。
NSPredicate是模糊查找类,就像一个正则表达式或者说是封装了一个sql语句似得,就是一个查找规则的封装,还好相关NSArray等都支持接收这个参数filteXX方法,闲话少数,请看代码。
import UIKit
class FreindsTabTableViewController: UITableViewController ,UISearchResultsUpdating,UISearchBarDelegate{
let friendsData=CreatDataUitls.creatFriendsData()
let searcherController=UISearchController(searchResultsController: nil)
let titleIndex=["A","B","C"]
var filterDatas=[[FriendModle]]()
override func viewDidLoad() {
super.viewDidLoad()
initSearchBar()
// 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()
}
func initSearchBar(){
searcherController.searchBar.tintColor=UIColor.blueColor()
searcherController.searchBar.placeholder="搜索联系人"
searcherController.searchResultsUpdater=self
searcherController.searchBar.delegate=self
searcherController.dimsBackgroundDuringPresentation=true
searcherController.hidesNavigationBarDuringPresentation=true
searcherController.searchBar.sizeToFit()
self.tableView.tableHeaderView=searcherController.searchBar
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
let searcheStr=searcherController.searchBar.text
let searPredicate=NSPredicate(format: "SELF CONTAINS %@", searcheStr!)
let n=friendsData?.count
let m=NSMutableArray()
for var i=0;i<n;++i{
let one=friendsData![i]
for var j=0;j<one.count;++j{
m.addObject(one[j])
}
let d=m.filteredArrayUsingPredicate(searPredicate)
var d1=[FriendModle]()
for var p=0;p<d.count;++p{
d1.append(d[p] as! FriendModle)
}
filterDatas.append(d1)
}
self.tableView.reloadData()
}
func searchBarBookmarkButtonClicked(searchBar: UISearchBar) {
<#code#>
}
func searchBarSearchButtonClicked(searchBar: UISearchBar) {
<#code#>
}
func searchBarTextDidBeginEditing(searchBar: UISearchBar) {
<#code#>
}
func searchBarTextDidEndEditing(searchBar: UISearchBar) {
<#code#>
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
if(self.searcherController.active){
return 1
}
return (friendsData?.count)!
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
if(self.searcherController.active){
filterDatas[section].count
}
return friendsData![section].count
}
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
if section==0{
return 0
}else{
return 25
}
}
override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 60
}
//返回索引数据源
override func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
return titleIndex
}
//设置每个header的title
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
if section==0{
return ""
}else{
return titleIndex[section-1]
}
}
//设置点击对应的index索引后移动到相应的section
override func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
return index+1
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell:UITableViewCell?
cell=tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
let imgView = cell!.viewWithTag(100)as!UIImageView
let text=cell!.viewWithTag(101) as!UILabel
if(self.searcherController.active){
imgView.image=filterDatas[indexPath.section][indexPath.row].img
text.text=filterDatas[indexPath.section][indexPath.row].name
}else{
imgView.image=friendsData![indexPath.section][indexPath.row].img
text.text=friendsData![indexPath.section][indexPath.row].name
}
return cell!
}
//如果不这么做切换到下个view的时候SearcherController会短暂的存在
override func viewWillDisappear(animated: Bool) {
if(self.searcherController.active){
self.searcherController.active=false
self.searcherController.searchBar.removeFromSuperview()
}
}
}
语法结构
- 使用
%@
对应数字,字符串,日期的替代值 - 使用
%K
对应要比较的属性,也就是KVC中的key - 使用
$变量名
来表示通配的变量,然后predicateWithSubstitutionVariables
来决定具体的变量值
基本比较
比较符号,都是针对于左边表达式和右边表达式
1. > 大于
2. > =大于等于
3. < 小于
4. <=小于等于
5. ==等于
6. != 或者<> 不等于
7. BETWEEN 介于两者之间,包括上下限
举个例子
let persons = NSMutableArray() persons.addObject(Person(name: "Jack Tomphon", age: 23)) persons.addObject(Person(name: "Mikle Steven", age: 25)) persons.addObject(Person(name: "Tacmk", age: 24))
let pridivateByAge5 = NSPredicate(format: "age BETWEEN { %@ , %@ }", NSNumber(int: 24),NSNumber(int: 25)) let result5 = persons.filteredArrayUsingPredicate(pridivateByAge5)
就是过滤24 <=age<=25
所以,可以看到Playground给出的结果是
"[name:Mikle Steven age:25, name:Tacmk age:24]"
复合比较
- && 或者AND 逻辑与
- || 或者 OR 逻辑或
- !或者NOT 逻辑非
较为简单,这里不举例子了
字符串比较
- BEGINSWITH 左边表达式以右边表达式开头
- CONTAINS 左边表达式包含右边表达式
- ENDSWITH 左边表达式以右边表达式结尾
- LIKE 左边表达式和右边表达式相似(简单的正则表达式匹配,?匹配一个字符,*匹配0个或者多个字符)
- MATCHES 可以实现较为复杂的曾则表达式匹配
- 用方括号加cd来不区分大小写和变音符号
- IN 左边的表达式在右边的集合里
匹配以Ja开头
let pridivateByName1 = NSPredicate(format: "name BEGINSWITH %@","Ja")
let result6 = persons.filteredArrayUsingPredicate(pridivateByName1) println(result6)
名字里包含ac,不区分大小写,并且年龄大于等于24
let pridivateByName2 = NSPredicate(format: "name CONTAINS %@ && age >= %@", "ac",NSNumber(int: 24)) let result7 = persons.filteredArrayUsingPredicate(pridivateByName2) println(result7)
复合正则表达式T[a-z]*k
let privatedivateByName3 = NSPredicate(format: "name MATCHES ‘T[a-z]*k‘")
let result8 = persons.filteredArrayUsingPredicate(privatedivateByName3)
名字是两者中的一个
let privatedivateByName4 = NSPredicate(format: "name IN {‘Tacmk‘,‘Jack Tomphon‘}")
let result9 = persons.filteredArrayUsingPredicate(privatedivateByName4)
基于Block的谓词
注意:基于Blcok的谓词不能用在CoreData的数据过滤上。基于Block能够灵活的定制谓词。
简单的Block定义age >24
let blockPredicate = NSPredicate { (person: AnyObject!, [NSObject : AnyObject]!) -> Bool in var result = false if let castResult = person as? Person{ if castResult.age > 24{ result = true } } return result } let result10 = persons.filteredArrayUsingPredicate(blockPredicate)