-1

I'm trying to segue from a search result in a tableview controller in swift 3 but when I use self.performSegue(withIdentifier: "teacherDetail", sender: self) it seems to hang when selecting a cell. If I tap the first cell it will show gray like it is selected, and then won't do anything unless I select another cell. Then, it will preform the segue to the detail view controller with the information from the first cell.

import UIKit

var name = ""

class DirectoryTC: UITableViewController, UISearchResultsUpdating {
    var teachers = ["Mr. Delano", "Mr. Antani", "Mr. Botelho", "Mr. Braga"]
    var filteredTeachers = [String]()

    var searchController: UISearchController!
    var resultsController = UITableViewController()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.resultsController.tableView.dataSource = self
        self.resultsController.tableView.delegate = self

        self.searchController = UISearchController(searchResultsController: self.resultsController)
        self.tableView.tableHeaderView = self.searchController.searchBar
        self.searchController.searchResultsUpdater = self
        definesPresentationContext = true
    }

    func updateSearchResults(for searchController: UISearchController) {
        self.filteredTeachers = self.teachers.filter{ (teacher:String) -> Bool in
            if teacher.lowercased().contains(self.searchController.searchBar.text!.lowercased())
            {
                return true
            }else
            {
                return false
            }
        }

        self.resultsController.tableView.reloadData()
    }

    // MARK: - Table view data source

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

        if tableView == self.tableView
        {
            return self.teachers.count
        }else
        {
            return self.filteredTeachers.count
        }

    }


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
    {
        let cell = UITableViewCell()

        if tableView == self.tableView
        {
            cell.textLabel?.text = self.teachers[indexPath.row]
        }else
        {
            cell.textLabel?.text = self.filteredTeachers[indexPath.row]
        }

        return cell
    }

    override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {

        DispatchQueue.main.async(){

            if tableView == self.tableView
            {
                name = self.teachers[indexPath.row]
            }else
            {
                name = self.filteredTeachers[indexPath.row]
            }

            self.performSegue(withIdentifier: "teacherDetail", sender: self)
        }

    }
}

And here is the swift file for the view controller I'm trying to segue to.

import UIKit

class DirectoryDetailVC: UIViewController{
    @IBOutlet weak var test: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        test.text = name
    }
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
JoshHolme
  • 303
  • 2
  • 15
  • 1
    Typo - change `didDeselectRowAt` to `didSelectRowAt`. – rmaddy Aug 29 '17 at 00:02
  • Also, why are you dispatching asynchronously; selection is a UI event so you will already be on the main queue – Paulw11 Aug 29 '17 at 00:06
  • Isn't it showing any compilation error in the DirectoryDetailsVC class? Because you're setting test's text to name and there is no name variable in that class!? – user3407319 Aug 29 '17 at 00:10
  • And why is the name variable declared outside the class in the DirectoryTC class? – user3407319 Aug 29 '17 at 00:13
  • I'm relatively new to iOS programming so I wasn't sure how to easily pass it through to the next ViewController. I declared it outside the class to make it a global variable so I could call it in the DirectoryDetailVC class. I dispatched asynchronously because in another thread here https://stackoverflow.com/questions/28509252/performseguewithidentifier-very-slow-when-segue-is-modal it said that it would fix it but I didn't have any luck with mine – JoshHolme Aug 29 '17 at 00:37
  • Is there a better way I should pass the name variable? – JoshHolme Aug 29 '17 at 00:38
  • @rmaddy thanks for pointing that out. That fixed my issue! If you want to submit it as an answer I can chose it as solved and give you the credit. – JoshHolme Aug 29 '17 at 00:45
  • @Paulw11 see my previous comment for my reasoning of declaring name outside of the class. Is there a better way to pass it to the next view controller? – JoshHolme Aug 29 '17 at 00:45
  • @user3407319 see my previous comment for my reasoning of declaring name outside of the class. Is there a better way to pass it to the next view controller? – JoshHolme Aug 29 '17 at 00:46
  • Google passing data between view controllers and you will find many ways to do it – user3407319 Aug 29 '17 at 00:47
  • The one i usually use is declare the same name variable in the second class and then override prepareForSegue method in the first class where you downcast the destination to your second class and then set the name variable as a property from there – user3407319 Aug 29 '17 at 00:49

2 Answers2

0

make sure that your story board View Controller name is teacherDetail - use

DispatchQueue.main.async { self.performSegue(withIdentifier: "teacherDetail", sender: self)}

instead of

self.performSegue(withIdentifier: "teacherDetail", sender: self)
Saeed Rahmatolahi
  • 1,317
  • 2
  • 27
  • 60
0

rmaddy caught it. It was a typo. "Typo - change didDeselectRowAtlectRowAt to didSelectRowAt"

JoshHolme
  • 303
  • 2
  • 15