Jamilah
Jamilah

Reputation: 165

How to pass TableViewCell value into new ViewController in Swift 3.0?

I have this JSON data

move.json

{
    "status":"ok",
    "movement":
                [
                    {
                        "refno":"REF 1",
                        "dtfrom":"2017-13-12"
                    },
                    {
                        "refno":"REF 2",
                        "dtfrom":"2017-13-13"
                    },
                    {
                        "refno":"REF 3",
                        "dtfrom":"2017-13-14"
                    },
                ]
}

So far, I managed to fetch the value into TableViewCell.

But my goal is to pass the value from ViewController.swift into MoveDetails.swift so the value can be display in MoveDetails.swift

And I have these four swift files. I'm having the problem on ViewController.swift and MoveDetails.swift. I'm not sure how to pass the value into new Controller.

The code as below.

ViewController.swift

import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    @IBOutlet weak var tableview: UITableView!
    var move: [Move]? = []
    override func viewDidLoad() {
        super.viewDidLoad()
        fetchData()
    }
    func fetchData() {
        let urlRequest = URLRequest(url: URL(string: "http://localhost/move.json")!)
        let task = URLSession.shared.dataTask(with: urlRequest) {
            (data,response,error)in
            if error != nil { return }

            self.move = [Move]()
            do {
                let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: AnyObject]

                if let msFromJson = json["movement"] as? [[String: AnyObject]] {
                    for mFromJson in msFromJson {
                        let ms = Move()
                        if let refno   = mFromJson["refno"] as? String, let dtfrom  = mFromJson["dtfrom"] as? String {
                            ms.refno        = refno
                            ms.dtfrom       = dtfrom
                        }
                        self.move?.append(ms)
                    }
                }
                DispatchQueue.main.async {
                    self.tableview.reloadData()
                }
            }
            catch let error{ print(error)}
        }
        task.resume()
    }
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "movementstatusCell", for: indexPath) as! MoveCell

        cell.refnoLbl.text          = self.move?[indexPath.item].refno
        cell.dtfromLbl.text         = self.move?[indexPath.item].dtfrom
        return cell
    }
    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.move?.count ?? 0
    }
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let vc = self.storyboard?.instantiateViewController(withIdentifier: "MoveDetails") as! MoveDetails

        let selectedMove = self.move?[indexPath.item]
         vc.refnoString = selectedMove.refno
        vc.dtfromString= selectedMove.dtfrom
        self.navigationController?.pushViewController(vc, animated: true)
    }
}

MoveCell.swift

import UIKit
class MoveCell: UITableViewCell {

    @IBOutlet weak var dtfromLbl: UILabel!
    @IBOutlet weak var refnoLbl: UILabel!    
    override func awakeFromNib() {
        super.awakeFromNib()
    }
    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }
}

Move.swift (NSObject)

import UIKit
class Move: NSObject {
    var refno: String?
    var dtfrom: String?
}

MoveDetails.swift

import UIKit
class MoveDetails: UIViewController {

    @IBOutlet weak var refnoLbl: UILabel!
    @IBOutlet weak var dtfromLbl: UILabel!

    var refnoString: String!
    var dtfromString: String!

    override func viewDidLoad() { 
        super.viewDidLoad() 
        refnoString = refnoLbl.text
        dtfromString = dtfromLbl.text
    }
    override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() }
}

Appreciate if someone can help. Thanks.

Upvotes: 0

Views: 623

Answers (1)

Andreas Oetjen
Andreas Oetjen

Reputation: 10199

You will just have to set the properties of your MoveDetails view controller. And as a suggestion

  • Instead of storing refnoString and dtfromString properties in MoveDetails, you could just store one property of type Move:
  • Cache MoveDetails view controller to reuse it
  • Implement viewDidAppear to update the MoveDetails outlets

So:

class ViewController: UIViewController, UITableViewDelegate,    UITableViewDataSource {

    var detailsVC : MoveDetails?

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if (detailsVC == nil) {
            detailsVC = self.storyboard?.instantiateViewController(withIdentifier: "MoveDetails") as! MoveDetails
        }
        detailsVC.move = self.move?[indexPath.item]
        self.navigationController?.pushViewController(detailsVC , animated: true)
    }
}

Then, override viewDidAppear in MoveDetails view controller and there you just fill in the values into the text label outlets.

class MoveDetails: UIViewController {

    @IBOutlet weak var refnoLbl: UILabel!
    @IBOutlet weak var dtfromLbl: UILabel!

    var move:Move?

    override func func viewDidAppear(_ animated: Bool) {
        refnoLbl.text = move?.refno
        dtfromLbl.text = move?.dtfrom
    }
}

Syntax errors cause because I currently have no Xcode available to do the checking

Upvotes: 2

Related Questions