Search code examples
iosswiftuilabelsegue

Pass Data (Label) from TableViewCell to another ViewController


I want to pass the Label from a TableViewCell to a ViewController when I click on the Cell. In the end it should be like twitter, that if you click on a cell with a Label you get passed on a detailViewController with the same Label init. My Code doesn't work as I just get the blanket Label from the Storyboard...

import UIKit
import Firebase

class JobTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {

@IBOutlet weak var tableView: UITableView!
var valueToPass:String!


 func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true
}

 func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
    // Arvice return to count jobs
    return jobs.count
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    print("You selected cell #\(indexPath.row)!")

    // Get Cell Label
    let indexPath = tableView.indexPathForSelectedRow!
    let currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell

    let valueToPass = currentCell.textLabel?.text
    print("value: \(valueToPass)")

    performSegue(withIdentifier: "toDetails", sender: valueToPass)
}

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
    let cell = tableView.dequeueReusableCell(withIdentifier: "JobCell", for: indexPath) as! JobTableViewCell
    let job = jobs[indexPath.row]
    cell.job = job

    //spacing
    cell.contentView.backgroundColor = UIColor.clear

    let whiteRoundedView : UIView = UIView(frame: CGRect(x: 10, y: 8, width: self.view.frame.size.width - 20, height: 120))

    whiteRoundedView.layer.backgroundColor = CGColor(colorSpace: CGColorSpaceCreateDeviceRGB(), components: [0.36, 0.39, 0.40, 1.0])
    whiteRoundedView.layer.masksToBounds = false
    whiteRoundedView.layer.cornerRadius = 2.0
    whiteRoundedView.layer.shadowOffset = CGSize(width: 0, height: 0)
    whiteRoundedView.layer.shadowOpacity = 0.0

    cell.contentView.addSubview(whiteRoundedView)
    cell.contentView.sendSubview(toBack: whiteRoundedView)

    cell.emojiLabel.text = cell.emojiString

    return cell
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
    if segue.identifier == "toDetails" {
        let destinationViewController = segue.destination as! JobDetailViewController
        destinationViewController.valueToPass = (sender as? String)!
    }
}

My Cell:

import UIKit
import Firebase

class JobTableViewCell: UITableViewCell {

@IBOutlet weak var jobLabel: UILabel!

var job: Job! {
    didSet {
        jobLabel.text = job.text
    }
}
}

Job.Swift:

import Foundation
import Firebase

class Job{

var text: String = ""
let ref: DatabaseReference!

init(text: String) {
    self.text = text
    ref = Database.database().reference().child("jobs").childByAutoId()
}

init(snapshot: DataSnapshot)
{
    ref = snapshot.ref
    if let value = snapshot.value as? [String : Any] {
        text = value["text"] as! String
    }
}

func save() {
    ref.setValue(toDictionary())
}

func toDictionary() -> [String : Any]
{
    return [
        "text" : text,
    ]
}
}

And in my DestinationController:

import UIKit
import Firebase

class JobDetailViewController: UIViewController {

 @IBOutlet weak var jobDetail: RoundText!



var valueToPass: String = ""

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    jobDetail.text = valueToPass
}

override func viewDidLoad() {
    super.viewDidLoad()

    title = "Jobinformation"
}
}

Solution

  • Quick solution:

    1. Change performSegue(withIdentifier: "yourSegueIdentifer", sender: self) to performSegue(withIdentifier: "yourSegueIdentifer", sender: valueToPass)

    2.Your prepare for Segue method should looks like this:

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
         if segue.identifier == "yourSegueIdentifer" {
             let destinationViewController = segue.destination as!   AnotherViewController
                 destinationViewController.valueToPass = sender as? String
        }
    }
    
    1. On AnotherViewController create var valuteToPass: String = "" and set your label.text = valueToPass

    But I think you should not use currentCell.textLabel.text value, instead use the original value. (like if you set your currentCell as cell.textLabel.cell = array[indexPath.row], your valueToPass should be valueToPass = array[indexPath.row])

    EDIT:

    You use didDeselectRowAt method, instead of didSelectRowAt.

    Change func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) to func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)

    Don't use global variable, create it in didSelectRowAt.

        func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        print("You selected cell #\(indexPath.row)!")
    
        // Get Cell Label
        let indexPath = tableView.indexPathForSelectedRow!
        let currentCell = tableView.cellForRow(at: indexPath)! as UITableViewCell
    
        let valueToPass = currentCell.textLabel?.text
        print("value: \(valuteToPass)")
    
        performSegue(withIdentifier: "toDetails", sender: valueToPass)
    }
    

    On DestinationController:

    class DestinationController: UIViewController {
    
    var valuteToPass: String = ""
    
      override func viewDidLoad() {
        super.viewDidLoad()
       jobLabel.text = valueToPass
       }
    
    }
    

    EDIT2

    JobTableViewController

    1. delete var valueToPass:String!

    Change let valueToPass = jobs[indexPath.row].text instead of let valueToPass = currentCell.textLabel?.text I checked this change in your code, this will work.