Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to update label with didSelectRowAtIndexPath

I have a tableView populated with information from a JSON array. When I click on that cell, it segues into a DetailsViewController where it should display

  1. a label that displays the text of the cell that was clicked on (in my case it is title, or entry name)
  2. a label that shows the time corresponding to that cell's title
  3. a label that shows id corresponding to that cell's title. All this information (ex. time, id) come from my JSON array.

I've already got #1 working, #2 is what I need help on (and I'm sure after I figure that out I can do the id label easily). I'm using didSelectRowAtIndexPath for updating the time label and the program runs fine but the time label isn't updated with info. The label doesn't even show up.

Here is my code in my tableViewController file:

class EarthTableViewController: UITableViewController {
    var info = [AppModel]()



    func getEarthquakeInfo(completion: (results : NSArray?) ->Void ){

        DataManager.getEarthquakeDataFromFileWithSuccess {
            (data) -> Void in

                let json = JSON(data: data)


                if let JsonArray =  json.array {

                    for appDict in JsonArray {
                        var ids: String? = appDict["id"].stringValue
                        var title: String? = appDict["title"].stringValue
                        var time: String? = appDict["time"].stringValue
                        var information = AppModel(idEarth: ids, title: title, time: time)

                        self.info.append(information)
                        completion(results: self.info)
                    }


            }

        }



    }


    override func viewDidLoad() {
        super.viewDidLoad()
        getEarthquakeInfo { (info) in
            self.tableView.reloadData()
        }
    }




    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) ->   UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell
        let infoArray = self.info
        cell.textLabel!.text = info[indexPath.row].title
        return cell

    }

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {

        if segue.identifier == "SEGUE" {
            let vc = segue.destinationViewController as DetailsViewController
            let cell = (sender as UITableViewCell)
            let title = cell.textLabel!.text
            vc.titleData = title

        }
    }




    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

                let time = info[indexPath.row].time
                let destinationVC = DetailsViewController()
                destinationVC.timeData = time


    }

My DetailsViewController file:

class DetailsViewController: UIViewController {


    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var idLabel: UILabel!

    @IBOutlet weak var timeLabel: UILabel!
    var titleData: String!
    var idData: String!
    var timeData: String!

    override func viewDidLoad() {
        super.viewDidLoad()
        let earthInfo = EarthTableViewController()
        titleLabel.text = titleData
        idLabel.text = idData
       timeLabel.text = timeData
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }



}

And just in case here is my AppModel.swift file that I used:

class AppModel: NSObject, Printable {
    let idEarth: String
    let title: String
    let time: String


    override var description: String {
        return "ID: \(idEarth), TITLE: \(title), TIME: \(time), \n"
    }

    init(idEarth: String?, title: String?, time: String?) {
        self.idEarth = idEarth ?? ""
        self.title = title ?? ""
        self.time = time ?? ""
    }

}

Any help would be appreciated.

UPDATE WITH ANSWER: Using the help from the people's comments down below I was able to figure out the answer to my own question. Turns out, I didn't even need to use didSelectRowAtIndexPath. The reason why I added that in the first place was because when tried to do let time = info[indexPath.row].time in prepareForSegue it didn't work since I didn't add the code that was needed for me to do that. Now all the labels are displaying info properly.

 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {

        if segue.identifier == "SEGUE" {
            let vc = segue.destinationViewController as DetailsViewController
            let cell = (sender as UITableViewCell)
            let title = cell.textLabel!.text
            vc.titleData = title

            if let indexPath = self.tableView.indexPathForSelectedRow(){
            let time = info[indexPath.row].time
                println("\(time)")
                vc.timeData = time
            let id = info[indexPath.row].idEarth
                vc.idData = id

            }
        }
    }
like image 875
videoperson Avatar asked Oct 21 '25 15:10

videoperson


1 Answers

This seems to a simple mistake regarding how you're passing the data between the two view controllers.

override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
    if segue.identifier == "SEGUE" {
        let vc = segue.destinationViewController as DetailsViewController
        let cell = (sender as UITableViewCell)
        let title = cell.textLabel!.text
        vc.titleData = title
    }
}

override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let time = info[indexPath.row].time
    let destinationVC = DetailsViewController()
    destinationVC.timeData = time
}

The issue is in the fact that you are sending the information to a UIViewController that isn't being presented. In didSelectRowAtIndexPath: you're initializing a view controller and sending the data to it correctly, but that specific instance is never shown. To fix this, you have a few options. You can either choose to continue using an Action Segue and pass the data within the segue using performSegueWithIdentifier: & prepareForSegue:, or you can choose to utilize instantiateViewControllerWithIdentifier: and manually present said view controller.

like image 180
Jeffrey Avatar answered Oct 23 '25 07:10

Jeffrey