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
    }

 

posted @ 2016-06-12 19:56  Alex_sun  阅读(230)  评论(0编辑  收藏  举报