如何从充满搜索控制器结果的表中进行 Segue



旧的UISearchDisplayController类现已弃用,相反,我们必须使用新的UISearchController。旧类中曾经有一个名为"SearchResultsTableView"的属性,但它已从新类中消失。

我用数据和所有工作按预期填充表格 - 包括将每一行的详细信息转移到另一个场景。我在那里扔了一个搜索栏(以编程方式 - 使用新的 searchController),它成功地用找到的任何结果重新加载了原始表。但是,当在搜索后触摸所选行时,传递的 segue 是原始表行的 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()
}
}

您需要考虑到这样一个事实,即根据搜索结果,您将在表视图中具有不同的数据。您仍然可以使用 self.tableView.indexPathForSelectedRow .

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

例:

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()
    }
}

现在,您可以使用 filteredData 实现所有UITableViewDataSourceUITableViewDelegate方法。

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

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

最新更新