如何在 Swift 3.0 中将 TableViewCell 值传递给新的 ViewController?

Posted

技术标签:

【中文标题】如何在 Swift 3.0 中将 TableViewCell 值传递给新的 ViewController?【英文标题】:How to pass TableViewCell value into new ViewController in Swift 3.0? 【发布时间】:2017-02-14 07:43:05 【问题描述】:

我有这个 JSON 数据

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"
                    ,
                ]

到目前为止,我设法将值提取到 TableViewCell 中。

但我的目标是将 ViewController.swift 中的值传递到 MoveDetails.swift 中,以便可以在 MoveDetails.swift 中显示该值

我有这四个 swift 文件。我在 ViewController.swift 和 MoveDetails.swift 上遇到问题。我不确定如何将值传递给新的控制器。

代码如下。

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

感谢有人可以提供帮助。谢谢。

【问题讨论】:

这个已经被问了好几次了,到目前为止你尝试了哪些链接? ***.com/questions/28315133/… 。但我不确定为什么 MoveDetails.swift 上的值仍然为空 【参考方案1】:

您只需设置MoveDetails 视图控制器的属性。作为建议

您可以只存储Move 类型的一个属性,而不是将refnoStringdtfromString 属性存储在MoveDetails 中: 缓存 MoveDetails 视图控制器以重用它 实施viewDidAppear 以更新MoveDetails 出口

所以:

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)
    

然后,在MoveDetails 视图控制器中覆盖viewDidAppear,然后将值填入文本标签出口。

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
    

语法错误是因为我目前没有可用的 Xcode 进行检查

【讨论】:

viewDid load 是填充文本标签的更好位置 @Inder 但前提是你总是创建一个新的MoveDetails 视图控制器。如果你重用它,你最好使用 viewDidAppear @AndreasOetjen 是的,你是对的,这就是 instantiateViewController 所做的 你能检查我上面的代码吗? @AndreasOetjen。该值仍未出现在 MoveDetails.swift 上。 @Jamilah,你做错了(应该是refnoLbl.text = refnoString 等) - 检查我修改后的答案

以上是关于如何在 Swift 3.0 中将 TableViewCell 值传递给新的 ViewController?的主要内容,如果未能解决你的问题,请参考以下文章

在swift 3.0中将坐标数组转换为geojson字符串

如何在 Swift 3.0 中使用 keysSortedByValue?

Swift:如何使用编辑按钮删除并停用滑动删除?

如何在 swift 3.0 中编写此代码,特别是如何在 swift3 中使用宏?

如何使用 Swift 2.3 和 3.0 编译模块?

如何在 slick 3.0 中将 Rep[T] 转换为 T?