ScarletEnvy
ScarletEnvy

Reputation: 921

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.

Upvotes: 2

Views: 134

Answers (2)

NehaK
NehaK

Reputation: 2727

You can perform segue manually in didSelectRowAtIndexPath by searching position of selected String from array, then you can get correct position -

Example -

func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) {

    let Cell: AnyObject = self.tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)

    let str: String=  Cell.textLabel.text
    // now find str in array and then get position
    int pos = getPositionOfStringInArray(str)        

    // now perform segue for pos
    //code...

}

Upvotes: 0

pbasdf
pbasdf

Reputation: 21536

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.)

Upvotes: 3

Related Questions