UISearchBar -- 备忘
搜索功能的备忘
UISearchBar
UISearchBar是一个搜索栏,继承自UIView,也是常用的控件之一,所以特别写一篇备忘方便以后做工具文章。
例子:
let searchBar = UISearchBar(frame: CGRectMake(0, 64, view.frame.size.width, 40)) searchBar.barStyle = .Default searchBar.placeholder = "请输入一些内容" searchBar.showsCancelButton = true searchBar.showsSearchResultsButton = true searchBar.tintColor = UIColor.orangeColor() searchBar.showsScopeBar = true searchBar.scopeButtonTitles = ["分组1", "分组2"] searchBar.selectedScopeButtonIndex = 1 searchBar.delegate = self view.addSubview(searchBar)
一些常用的属性方法(更多请参考官方文档):
- barStyle:搜索栏风格,(default, black)。
- text:搜索栏内的文字。
- placeholder:占位文字。
- showsCanclButton:是否显示取消按钮。
- tintColor:光标颜色。
- barTintColor:搜索栏背景颜色。
- showsScopeBar:是否显示附加按钮视图。
- scopeButtonTitles:设置了showsScopeBar后 可以设置每个按钮的title。
- selectedScopeButtonIndex:应该选中那个附加按钮。
- inputAccessoryView:键盘的附加视图。
- backgroundImage:搜索栏的背景图片。
- setShowsCancelButton(Bool, animated: Bool):是否显示取消按钮,可以使用动画。
- setBackgroundImage(UIImage?, forBarPosition: UIBarPosition, barMetrics: UIBarMetrics):设置背景图片。
- backgroundImageForBarPosition(UIBarPosition, barMetrics: UIBarMetrics):获取背景图片。
代理方法:
// 是否应该开始编辑 func searchBarShouldBeginEditing(searchBar: UISearchBar) -> Bool { return true } // 搜索栏开始编辑的回调 func searchBarTextDidBeginEditing(searchBar: UISearchBar) { print("begin editing") } // 是否应该结束编辑 func searchBarShouldEndEditing(searchBar: UISearchBar) -> Bool { return true } // 搜索栏结束编辑的回调 func searchBarTextDidEndEditing(searchBar: UISearchBar) { print("end editing") } // 当搜索栏内的文字发生变化时调用,返回是否允许改变。 func searchBar(searchBar: UISearchBar, shouldChangeTextInRange range: NSRange, replacementText text: String) -> Bool { print("\(range), \(text)") return true } // 取消按钮点击事件 func searchBarCancelButtonClicked(searchBar: UISearchBar) { print("cancel button click") searchBar.text = nil searchBar.resignFirstResponder() } // 点击了搜索按钮的回调 func searchBarSearchButtonClicked(searchBar: UISearchBar) { print("search button click") searchBar.resignFirstResponder() } // 搜索结果列表按钮被点击 func searchBarResultsListButtonClicked(searchBar: UISearchBar) { print("results list click") } // 当搜索栏的内容已经发生变化时调用 func searchBar(searchBar: UISearchBar, textDidChange searchText: String) { print(searchText) } // 点击了附加视图按钮后调用 func searchBar(searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) { print(selectedScope) }
UISearchDisplayController
需要注意的是 UISearchDisplayController并非继承于UIViewController 而是NSObject,所以它单靠本身不具备展示功能。
例子:
首先先声明需要的属性。
// MARK: 属性 let identifier = "cellIdentifier" weak var tableview: UITableView! var searchController: UISearchDisplayController! let datas = ["Alex", "Alice", "Alisa", "Andy", "Jack", "Ben", "Tom", "Jerry", "Edward", "Daniel", "Amy", "Anne", "Alan", "Danny", "Tony", "Tim", "Van", "Zack"] var filterDatas: [String]?
创建tableview,searchbar,searchdisplaycontroller,并建立相关关系 设置代理和数据源。
override func viewDidLoad() { super.viewDidLoad() // 创建tableview createTableview() // 创建搜索控制器 createSearchDisplayController() } func createTableview() { let tableview = UITableView(frame: CGRectMake(0, 0, view.frame.size.width, view.frame.size.height), style: .Plain) tableview.dataSource = self tableview.delegate = self tableview.registerClass(UITableViewCell.self, forCellReuseIdentifier: identifier) view.addSubview(tableview) self.tableview = tableview } func createSearchDisplayController() { let searchBar = UISearchBar(frame: CGRectMake(0, 0, view.frame.size.width, 44)) searchBar.placeholder = "搜索" tableview.tableHeaderView = searchBar let searchDisplayController = UISearchDisplayController(searchBar: searchBar, contentsController: self) searchDisplayController.searchResultsDelegate = self searchDisplayController.searchResultsDataSource = self searchDisplayController.delegate = self searchDisplayController.searchResultsTableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: identifier) searchController = searchDisplayController }
实现tableview的数据源和代理方法,主要区分是哪个tableview
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { if tableView == tableview { return datas.count } else { return filterDatas == nil ? 0 : filterDatas!.count } } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier(identifier, forIndexPath: indexPath) if tableView == tableview { cell.textLabel?.text = datas[indexPath.row] } else { cell.textLabel?.text = filterDatas?[indexPath.row] } return cell } func scrollViewWillBeginDragging(scrollView: UIScrollView) { if scrollView == tableview { searchController.searchBar.resignFirstResponder() } }
这里看下searchdisplaycontroller的代理方法,最后一个方法用于过滤数据
// search display controller 即将停止搜索。 func searchDisplayControllerWillEndSearch(controller: UISearchDisplayController) { print("searchDisplayControllerWillEndSearch") } // 即将开始搜索,当点击了searchBar时 此方法被第一个调用。 func searchDisplayControllerWillBeginSearch(controller: UISearchDisplayController) { print("searchDisplayControllerWillBeginSearch") } // 即将开始显示ResultsTableView。 func searchDisplayController(controller: UISearchDisplayController, willShowSearchResultsTableView tableView: UITableView) { print("willShowSearchResultsTableView") } // 已经开始搜索,当点击了searchBar时 此方法被第二个调用。 func searchDisplayControllerDidBeginSearch(controller: UISearchDisplayController) { print("searchDisplayControllerDidBeginSearch") } // search display controller 已经停止搜索。 func searchDisplayControllerDidEndSearch(controller: UISearchDisplayController) { print("searchDisplayControllerDidEndSearch") } // ResultsTableView已经被隐藏。 func searchDisplayController(controller: UISearchDisplayController, didHideSearchResultsTableView tableView: UITableView) { print("didHideSearchResultsTableView") } // 已经加载了resultTableview的回调,(注意:这并不是等resultTableview显示时才调用,而是加载了resultTableview就调用)。 func searchDisplayController(controller: UISearchDisplayController, didLoadSearchResultsTableView tableView: UITableView) { print("didLoadSearchResultsTableView") } // 已经显示ResultsTableView。 func searchDisplayController(controller: UISearchDisplayController, didShowSearchResultsTableView tableView: UITableView) { print("didShowSearchResultsTableView") } // ResultsTableView即将被隐藏。 func searchDisplayController(controller: UISearchDisplayController, willHideSearchResultsTableView tableView: UITableView) { print("willHideSearchResultsTableView") } // 即将卸载result tableview。 func searchDisplayController(controller: UISearchDisplayController, willUnloadSearchResultsTableView tableView: UITableView) { print("willUnloadSearchResultsTableView") } // 这个方法。。。还没弄清楚,没用到过😊 func searchDisplayController(controller: UISearchDisplayController, shouldReloadTableForSearchScope searchOption: Int) -> Bool { print(searchOption) return true } // 告诉Search display controller 是否应该刷新result tableview 传进来的参数searchString可以做筛选。 func searchDisplayController(controller: UISearchDisplayController, shouldReloadTableForSearchString searchString: String?) -> Bool { if let string = searchString { let predicate = NSPredicate(format: "self contains [cd] %@", string) let datasByObj = NSArray(array: datas) filterDatas = datasByObj.filteredArrayUsingPredicate(predicate) as? [String] } return true }