使用swift搜索栏类别过滤器

时间:2014-10-25 20:50:04

标签: swift xcode6 uisearchbar searchfiltercollection

我正在尝试实施一个搜索栏,根据人员和地点对搜索查询进行分类,以便用户在两类搜索之间来回切换。我有搜索栏为人们工作,但我无法弄清楚如何在两个搜索类别之间来回...我将如何实现这一点? 以下是代码......

提前谢谢!

//
//  SearchViewController.swift
//  TravelAppSwiftPrototype
//

import UIKit

class SearchViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate, UISearchBarDelegate, UISearchDisplayDelegate {

    var persons = [People]()
    var place = [Places]()

    var filteredPersons = [People]()
     var filteredPlaces = [Places]()

    override func viewDidLoad() {
        // Sample Data for PeopleArray
        self.persons = [People(category:"People", name:"Anthony Valentine"),
            People(category:"People", name:"Ben Matthews"),
            People(category:"People", name:"Mark Druffel"),
            People(category:"People", name:"Brittany Donnelly"),
            People(category:"People", name:"Thomas Meier"),
            People(category:"People", name:"Alex Curtis"),
            People(category:"People", name:"David Moss"),
            People(category:"People", name:"Sara Flege"),
            People(category:"People", name:"Mark Cuban"),
            People(category:"People", name:"Elon Musk"),
            People(category:"People", name:"Steve Jobs"),
            People(category:"People", name:"Steve Meier"),
            People(category:"People", name:"Dan Meier"),
            People(category:"People", name:"Christine Meier"),
            People(category:"People", name:"Bill Gates"),
            People(category:"People", name:"Matt Harris")]


        // Sample Data for PlacesArray
        self.place = [Places(category:"People", place:"Rome, Italy"),
            Places(category:"Places", place:"Paris, France"),
            Places(category:"Places", place:"Barcelona, Spain"),
            Places(category:"Places", place:"Girona, Spain"),
            Places(category:"Places", place:"Lloret de Mar, Spain"),
            Places(category:"Places", place:"London, United Kingdom"),
            Places(category:"Places", place:"Perth, Australia"),
            Places(category:"Places", place:"Berlin, Germany"),
            Places(category:"Places", place:"Lyon, France"),
            Places(category:"Places", place:"Munich, Germany"),
            Places(category:"Places", place:"Bruges, Belgium"),
            Places(category:"Places", place:"Buenes Aires, Argentina"),
            Places(category:"Places", place:"Milan, Italy")]



        // Reload the table
        self.tableView.reloadData()
    }

     //how to implement search filtering for places...?????
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if tableView == self.searchDisplayController!.searchResultsTableView {
            return self.filteredPersons.count
        } else {
            return self.persons.count
        }
    }



    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        //ask for a reusable cell from the tableview, the tableview will create a new one if it doesn't have any
        let cell = self.tableView.dequeueReusableCellWithIdentifier("SearchFriendsCell") as UITableViewCell

        var people : People
        // Check to see whether the normal table or search results table is being displayed and set the Candy object from the appropriate array
        if tableView == self.searchDisplayController!.searchResultsTableView {
            people = filteredPersons[indexPath.row]
        } else {
            people = persons[indexPath.row]
        }

        // Configure the cell
        cell.textLabel.text = people.name
        cell.accessoryType = UITableViewCellAccessoryType.DisclosureIndicator

        return cell
    }

    func filterContentForSearchText(searchText: String, scope: String = "All") {
        self.filteredPersons = self.persons.filter({( people : People) -> Bool in
            var categoryMatch = (scope == "All") || (people.category == scope)
            var stringMatch = people.name.rangeOfString(searchText)
            return categoryMatch && (stringMatch != nil)
        })
    }

    func searchDisplayController(controller: UISearchDisplayController!, shouldReloadTableForSearchString searchString: String!) -> Bool {
        let scopes = self.searchDisplayController!.searchBar.scopeButtonTitles as [String]
        let selectedScope = scopes[self.searchDisplayController!.searchBar.selectedScopeButtonIndex] as String
        self.filterContentForSearchText(searchString, scope: selectedScope)
        return true
    }

    func searchDisplayController(controller: UISearchDisplayController!,
        shouldReloadTableForSearchScope searchOption: Int) -> Bool {
            let scope = self.searchDisplayController!.searchBar.scopeButtonTitles as [String]
            self.filterContentForSearchText(self.searchDisplayController!.searchBar.text, scope: scope[searchOption])
            return true
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        self.performSegueWithIdentifier("FriendsDetail", sender: tableView)
    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
        if segue.identifier == "FriendsDetail" {
            let candyDetailViewController = segue.destinationViewController as UIViewController
            if sender as UITableView == self.searchDisplayController!.searchResultsTableView {
                let indexPath = self.searchDisplayController!.searchResultsTableView.indexPathForSelectedRow()!
                let destinationTitle = self.filteredPersons[indexPath.row].name
                candyDetailViewController.title = destinationTitle
            } else {
                let indexPath = self.tableView.indexPathForSelectedRow()!
                let destinationTitle = self.persons[indexPath.row].name
                candyDetailViewController.title = destinationTitle
            }
        }
    }



    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

}



//  Friends.swift
//  TravelAppSwiftPrototype
//
import Foundation

struct People {
    let category : String
    let name : String
}



//  Places.swift
//  TravelAppSwiftPrototype
//
import Foundation

struct Places {
    let category : String
    let place : String
}

3 个答案:

答案 0 :(得分:1)

关键是这个方法:

func filterContentForSearchText(searchText: String, scope: String = "All") {
    self.filteredPersons = self.persons.filter({( people : People) -> Bool in
        var categoryMatch = (scope == "All") || (people.category == scope)
        var stringMatch = people.name.rangeOfString(searchText)
        return categoryMatch && (stringMatch != nil)
    })
}

您需要以考虑范围按钮设置的方式编写该方法。然后,您将自己设置为搜索栏的委托,以便听取有关正在更改的范围按钮的信息。当它发生变化时,请进行过滤并重新加载结果表。

答案 1 :(得分:0)

或者您可以使用NSPredicate

func filterContentForSearchText(searchText: String, scope: String = "All") {
        var predicate : NSPredicate
        if scope == "All" {
            predicate = NSPredicate(format: "persons CONTAINS[cd] %@", searchText)
        } else {
            predicate = NSPredicate(format: "persons CONTAINS[cd] %@ AND place == %@", searchText, scope)
        }
        filteredPerson = (people as NSArray).filteredArrayUsingPredicate(predicate) as! [People]
}

因为你需要让你重新上课人们看起来像这样

class People: NSObject {
let place : String
let persons : String

init(place : String, persons : String) {
    self.place = place
    self.persons = persons
}

}

答案 2 :(得分:0)

为清楚起见,在“搜索栏”和“搜索显示控制器”的“范围图块”列表中创建一系列名称。确保它们与Scope Titles List的顺序相同。 (虽然你可以使用Ints)

var myscope:[String] = ["People",Places"]

更换你的func filterContentForSearchText(searchText:String,范围:String =" All"){

用一个调用所选范围的索引

 func searchDisplayController(controller: UISearchDisplayController, shouldReloadTableForSearchString searchString: String?) -> Bool {

        let selectedIndex = controller.searchBar.selectedScopeButtonIndex

        if filterForContentsOfSearchText(searchString!, scope: myScope[selectedIndex]) {

            return true
        }

        return false
    }

对于我来说,我使用开关来执行filterForContentsOfSearchText(searchString!,范围:myScope [selectedIndex])

的调用所需的任何操作
func filterForContentsOfSearchText( searchText: String, scope: String)-> Bool{

switch scope {

    case "People":

        if WHATEVER.containsString(searchText) {


        }
    case "Places":

        if WHATEVER.places.containsString(searchText) {



        }
        default:
        break;
    }
}