如何从填充搜索控制器结果的表中查询

时间:2015-06-18 18:31:25

标签: ios xcode swift uisearchcontroller

现在不推荐使用旧的UISearchDisplayController类,而是必须使用新的UISearchController。曾经有一个名为“SearchResultsTableView”的旧类中的属性,但它已从新类中删除。

我使用数据填充表格,所有工作都按预期进行 - 包括将每行的详细信息转换为另一个场景。我在那里抛出一个搜索栏(以编程方式 - 使用新的searchController),它成功地重新加载原始表与任何找到的结果。 然而,当在搜索之后触摸选定的行时,传递的segue是原始表行的恰好位于与现在触摸的行相同的位置! (即如果我选择当前搜索的第二行,下一个场景将会删除原始表格第二行的详细信息!)这是因为尽管行中的数据正在成功地重新填充搜索数据,但索引编号仍然是那些旧数据。

它曾经是旧类型,我们会这样检查:

if (self.resultSearchController.active) {
let indexPath = self.searchDisplayController!.searchResultsTableView.indexPathForSelectedRow()
} else {
let indexPath = self.tableView.indexPathForSelectedRow()

所以我认为使用旧的UISearchDisplayController类实际上有一个新表,而使用新的SearchController类只能在旧表中获得新行?这完全没有意义!

以下是每个请求的完整代码:

import UIKit
import Foundation
class secondTableViewController: UITableViewController, UITableViewDelegate, UITableViewDataSource, UISearchResultsUpdating {

var filteredTableData = [String]()
var resultSearchController = UISearchController()




//these 2 are standard for the title and subtitle
var TableTitle:Array< String > = Array < String >()
var TableSub:Array< String > = Array < String >()

//the following are for my seque to next scene
var the_fname:Array< String > = Array < String >()
var the_basics:Array< String > = Array < String >()
var the_p_method:Array< String > = Array < String >()
var the_seats:Array< String > = Array < String >()
var the_notes:Array< String > = Array < String >()
var the_tableData:Array< String > = Array < String >()





override func viewDidLoad() {


    tableView.delegate = self
    tableView.dataSource = self


    self.title = currentBus


    super.viewDidLoad()

    self.resultSearchController = ({
        let controller = UISearchController(searchResultsController: nil)



        controller.searchResultsUpdater = self
        controller.dimsBackgroundDuringPresentation = false
        controller.searchBar.sizeToFit()

        self.tableView.tableHeaderView = controller.searchBar

        return controller
    })()

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




    var url = "http://the_path_to_my_json_file"

    get_data_from_url(url)

}



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

// MARK: - Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    // #warning Potentially incomplete method implementation.
    // Return the number of sections.
    return 1
}


override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // 2
    if (self.resultSearchController.active) {
        return self.filteredTableData.count
    }
    else {
        return TableTitle.count
    }
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = self.tableView.dequeueReusableCellWithIdentifier("secondtableCell", forIndexPath: indexPath) as! UITableViewCell

    // Configure the cell...
if (self.resultSearchController.active) {
cell.textLabel?.text = filteredTableData[indexPath.row]
//cell.detailTextLabel?.text = TableSub[indexPath.row]
}else{
cell.textLabel?.text = TableTitle[indexPath.row]
cell.detailTextLabel?.text = TableSub[indexPath.row]



    }
    return cell



}


func get_data_from_url(url:String)
{
    let httpMethod = "GET"
    let timeout = 15
    let url = NSURL(string: url)

    let urlRequest = NSMutableURLRequest(URL: url!,
        cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData,
        timeoutInterval: 15.0)
    let queue = NSOperationQueue()
    NSURLConnection.sendAsynchronousRequest(
        urlRequest,
        queue: queue,
        completionHandler: {(response: NSURLResponse!,
            data: NSData!,
            error: NSError!) in
            if data.length > 0 && error == nil{
                let json = NSString(data: data, encoding: NSASCIIStringEncoding)
                self.extract_json(json!)
            }else if data.length == 0 && error == nil{
                println("Nothing was downloaded")
            } else if error != nil{
                println("Error happened = \(error)")
            }
        }
    )
}






func extract_json(data:NSString)
{
    var parseError: NSError?
    let jsonData:NSData = data.dataUsingEncoding(NSASCIIStringEncoding)!
    let json: AnyObject? = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: &parseError)
    if (parseError == nil)
    {
        if let my_pass_list = json as? NSArray
        {
            for (var i = 0; i < my_pass_list.count ; i++ )
            {
                if let each_pass = my_pass_list[i] as? NSDictionary
                {
                    if let fname = each_pass["fname"] as? String
                    {
                        if let lname = each_pass["lname"] as? String
                        {
                            if let numofseats = each_pass["numofseats"] as? String
                            {
                                if let showed_up = each_pass["showed_up"] as? String
                                {
                                    if let res_id = each_pass["resnum"] as? String
                                    {
                                        if let res_notes = each_pass["res_notes"] as? String
                                        {
                                            if let payment_description = each_pass["payment_description"] as? String
                                            {




                                                // the_tableData.append(fname)
                                                the_fname.append(fname)
                                                the_basics.append(fname + " " + lname)
                                                the_p_method.append(payment_description)
                                                the_seats.append(numofseats)
                                                the_notes.append(res_notes)

                                                TableTitle.append(fname + " " + lname)
                                                TableSub.append("Seats Reserved: " + numofseats + ". Showed Up: " + showed_up + ". Notes:" + res_notes)

                                                the_tableData = TableTitle
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    do_table_refresh();
}


func do_table_refresh()
{
    dispatch_async(dispatch_get_main_queue(), {
        self.tableView.reloadData()
        return
    })
}






// 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].

    var thirdScene = segue.destinationViewController as! customer_details_View_Controller

        if let indexPath = self.tableView.indexPathForSelectedRow() {

            /*
so what I'm missing is to be able to check
if (self.resultSearchController.active) {
and if yes have indexPath be the self.resultSearchController.resultSearchTableView.indexPathForSelectedRow() {
or something of that nature
*/

            thirdScene.dotrav = todayString
            thirdScene.from = currentBus
            thirdScene.basics = the_basics[indexPath.row]
            thirdScene.p_method = the_basics[indexPath.row]
            thirdScene.seats = the_tableData[indexPath.row]
            thirdScene.notes = the_notes[indexPath.row]



        }
          // Pass the selected object to the new view controller.
}


func updateSearchResultsForSearchController(searchController: UISearchController)
{
    filteredTableData.removeAll(keepCapacity: false)

    let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text)
    let array = (the_tableData as NSArray).filteredArrayUsingPredicate(searchPredicate)
    filteredTableData = array as! [String]

    self.tableView.reloadData()
}
}

1 个答案:

答案 0 :(得分:0)

您需要根据搜索结果说明您将在tableView中拥有不同的数据。您仍然可以使用self.tableView.indexPathForSelectedRow

我所做的是保留对我的基础数据的引用,然后保留对我的过滤数据的引用,并始终在tableView中显示我的过滤数据。如果我的searchBar没有文本,那么我的过滤数据就等于我的基础数据。

示例:

class MyTableViewController: UITableViewController, UISearchResultsUpdating {

    var data: [String] = ["One", "Two", "Three", "Four", "Five"]

    var filteredData: [String]!

    var searchController: UISearchController!


    override func viewDidLoad() {
        super.viewDidLoad()
        setUpSearchController()
        setFilteredDataForCurrentSearch()
    }

    private func setUpSearchController() {
        searchController = UISearchController(searchResultsController: nil)
        searchController.searchResultsUpdater = self
        self.tableView.tableHeaderView = searchController.searchBar
    }


    private func setFilteredDataForCurrentSearch() {
        if let searchString = searchController.searchBar.text where !searchString.isEmpty {
            filteredData = data.filter({ (string: String) -> Bool in

                return searchString.rangeOfString(string, options: NSStringCompareOptions.CaseInsensitiveSearch) != nil

            })
        } else {
            filteredData = data
        }
    }

    func updateSearchResultsForSearchController(searchController: UISearchController) {
        setFilteredDataForCurrentSearch()
    }

}

现在,您可以使用UITableViewDataSource实现所有UITableViewDelegatefilteredData方法。

prepareForSegue中,您可以检索正确的选定对象,如:

let indexPath = tableView.indexPathForSelectedRow()
let selectedObject = filteredData[indexPath.row]