Search code examples
iosswiftuitableviewtext-filesuisearchcontroller

UISearchController for TableView


This is what my Table View looks like. Each cell Strings a text from a .txt enter image description here

Search Filter works fine. But When I select one of the results e.g. "How" it prints the the Content of "Hello" instead. enter image description here

I'm thinking this is probably because "Hello" is programmed as the first String so it will always be the result of the first cell when clicked. I am needing help with figuring out how the search results are linked to it's own content. if that makes any sense?

Here's the code below. The code reads from .txt file swell as search the text file. the results when clicked on do not match.

import UIKit

class title_ViewController: UITableViewController, UISearchResultsUpdating {
var SongTitle = [String]()
var SongLyrics = [LText]()
var filteredSongs = [String]()
var resultSearchController = UISearchController()

override func viewDidLoad() {
    super.viewDidLoad()

    self.resultSearchController = UISearchController(searchResultsController:     nil)
    self.resultSearchController.searchResultsUpdater = self

    self.resultSearchController.dimsBackgroundDuringPresentation = false
    self.resultSearchController.searchBar.sizeToFit()

    self.tableView.tableHeaderView = self.resultSearchController.searchBar

    self.tableView.reloadData()

    if let path = NSBundle.mainBundle().pathForResource("DataBase", ofType:     "txt"){
        do {
            let stringFromFile = try String(contentsOfFile:path, encoding:     NSUTF8StringEncoding)
            var Title: [String] =     stringFromFile.componentsSeparatedByString("@")
            Title.removeAtIndex(0)
            //Seperates the Title from the Lyrics
            var t1 = Array(Title[0].componentsSeparatedByString("^"))
            t1.removeAtIndex(0)

            SongTitle = Title
            SongLyrics = [LText(LyricsText: t1)]

        }catch{
            print(error)
        }
    }
}

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

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

    if self.resultSearchController.active{
        return self.filteredSongs.count
    }else{
        return self.SongTitle.count
    }
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let Cell: AnyObject = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
    Cell.textLabel?!.text = SongTitle[indexPath.row]


    if self.resultSearchController.active{
        Cell.textLabel?!.text = self.filteredSongs[indexPath.row]
    }else{
        Cell.textLabel?!.text = self.SongTitle[indexPath.row]
    }


    return Cell as! UITableViewCell

}

func updateSearchResultsForSearchController(searchController: UISearchController) {
    self.filteredSongs.removeAll(keepCapacity: false)
    let searchPredicate = NSPredicate(format: "SELF CONTAINS[c]%@", searchController.searchBar.text!)

    let array = (self.SongTitle as NSArray).filteredArrayUsingPredicate(searchPredicate)
    self.filteredSongs = array as! [String]
    self.tableView.reloadData()
}


override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    let indexPath: NSIndexPath = self.tableView.indexPathForSelectedRow!
    let DestViewController = segue.destinationViewController as! ViewController

    DestViewController.LyricString = SongTitle[indexPath.row]
}
}

any help is welcomed, thanks in advance.


Solution

  • The problem lies in your prepareForSegue. You need to amend it to test whether the searchController is active. If so, you should use filteredSongs to determine which song to pass to the destination VC, rather than SongTitle:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        let indexPath: NSIndexPath = self.tableView.indexPathForSelectedRow!
        let DestViewController = segue.destinationViewController as! ViewController
    
        if self.resultSearchController.active {
            DestViewController.LyricString = self.filteredSongs[indexPath.row]
        }else{
            DestViewController.LyricString = self.SongTitle[indexPath.row]
        }
    }
    

    (As an aside, it is convention that variable names should start with a lowercase letter - songTitle not SongTitle, etc.)