传递数据 Tableview -> Viewcontroller

Posted

技术标签:

【中文标题】传递数据 Tableview -> Viewcontroller【英文标题】:Passing Data Tableview -> Viewcontroller 【发布时间】:2016-11-20 13:38:17 【问题描述】:

我有这个表视图,我想将用户名传递给视图控制器并在标签中显示它,但它不起作用。用户名来自 firebase 数据库。我还检查了其他问题,但无法将其应用于我的问题。我不是编码专家:

import Foundation
import UIKit
import Firebase
import FirebaseDatabase
import FirebaseAuth

struct user 
     let username : String!


class MainScreen: UITableViewController 

     var Users = [user]()

     override func viewDidLoad() 

     let databaseRef = FIRDatabase.database().reference()

     databaseRef.child("users").queryOrderedByKey()
                .observe(.childAdded, with:  snapshot in

        print(snapshot)
        let username = (snapshot.value as? NSDictionary)!["username"] as! String
        print(username)
        self.Users.append(user(username: username))
        self.tableView.reloadData()
        print(self.Users)
    )


override func tableView(_ tableView: UITableView, 
                       numberOfRowsInSection section: Int) -> Int 
    return Users.count


override func tableView(_ tableView: UITableView, 
                        cellForRowAt indexPath: IndexPath) -> UITableViewCell 

    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")
    let nameLbl = cell?.viewWithTag(1) as! UILabel
    nameLbl.text = self.Users[indexPath.row].username
    return cell!
    

@IBAction func ShowDetail(_ sender: Any) 
    var selectedLabel:String?

    func tableView(tableView: UITableView, 
                    didSelectRowAtIndexPath indexPath: NSIndexPath) 
        print("Row \(indexPath.row)selected")
        selectedLabel = self.Users[indexPath.row].username
        performSegue(withIdentifier: "detailView", sender: self)
    

    func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 

        if(segue.identifier == "detailView") 
            let vc = segue.destination as! CallDetail
            vc.stringPassed = selectedLabel!
        
     

而接收的 ViewController 看起来像这样:

import UIKit

class CallDetail: UIViewController 

     @IBOutlet weak var UserName: UILabel!
     var stringPassed = String()

     override func viewDidLoad() 
         super.viewDidLoad()

         UserName = stringPassed.text
     

【问题讨论】:

func Sh​​owDetail(_ sender: Any) 方法的目的是什么?您应该在同一类范围级别上实现其内部方法 你能告诉我们什么不起作用吗?例如,在您的观察闭包中, print(snapshot) 是否打印快照? print(userName) 是否打印用户名?你在哪里“传递”数据?它似乎存储在一个数组中,然后在实例化 viewController 后分配给一个变量(未传递用户名) 嗨,Jay,很抱歉不够精确。从我的角度来看,唯一不起作用的是数据的传递。因此,新 Viewcontroller 中的标签保持空白。我将数据传递给另一个视图控制器,并且用户名应该出现在标签字段中。本质上,我尝试构建一个带有细节的表格视图(Viewcontroller 中的细节)。 【参考方案1】:

didSelectRowAtIndexPathprepareForSegue 方法都应该在@IBAction func ShowDetail(_ sender: Any) 之外(其实我想不通它的用途):

selectedLabel声明为实例变量并分离方法:

import Foundation
import UIKit
import Firebase
import FirebaseDatabase
import FirebaseAuth

struct user 
    let username : String!


class MainScreen: UITableViewController 

    // 'selectedLabel' should be here:
    var selectedLabel:String?

    var Users = [user]()

    override func viewDidLoad() 

        let databaseRef = FIRDatabase.database().reference()

        databaseRef.child("users").queryOrderedByKey().observe(.childAdded,    with: 
            snapshot in

            print(snapshot)

            let username        = (snapshot.value as? NSDictionary)!["username"] as! String

            print(username)

            self.Users.append(user(username: username))

            self.tableView.reloadData()

            print(self.Users)

        )
    

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return Users.count
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 

        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")

        let nameLbl = cell?.viewWithTag(1) as! UILabel

        nameLbl.text = self.Users[indexPath.row].username

        return cell!

    

    func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) 
        print("Row \(indexPath.row)selected")
        selectedLabel = self.Users[indexPath.row].username
        performSegue(withIdentifier: "detailView", sender: self)
    

    func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) 
        if(segue.identifier == "detailView") 
            let vc = segue.destination as! CallDetail

            vc.stringPassed = selectedLabel!
        
    

    // just remove it if you don't need it...
    @IBAction func ShowDetail(_ sender: Any) 

    


另外,请确保 tableView 数据源和委托已连接到 viewController。

【讨论】:

感谢 Ahmed,但它仍然无法正常工作。我在编译器中有以下错误:致命错误:在展开可选值时意外发现 nil 在DetailViewController中产生错误: class CallDetail: UIViewController @IBOutlet weak var UserName: UILabel! var stringPassed:字符串?覆盖 func viewDidLoad() super.viewDidLoad() UserName.text = stringPassed 当将数据从单元格中的按钮传递到另一个视图控制器时,这对我来说很成功。你如何让它与部分一起工作?就像说在页脚单元格中调用它以将标签数据传递给另一个视图控制器。我现在得到的结果仅显示其中一个部分的相同标签数据【参考方案2】:

首先你需要删除

tableView(tableView: UITableView, didSelectRowAtIndexPath,因为如果您已将 tableView 委托设置为 viewController,它将在您单击单元格时自动调用。

prepareForSegue 将在performSegue(withIdentifier: "detailView", sender: self) 之后调用并删除ShowDetail(_ sender: Any) 这不是必需的。

并更改这些行

let nameLbl = cell?.viewWithTag(1) as! UILabel

nameLbl.text = self.Users[indexPath.row].username

cell.textLabel?.text = self.Users[indexPath.row].username

【讨论】:

以上是关于传递数据 Tableview -> Viewcontroller的主要内容,如果未能解决你的问题,请参考以下文章

如何将单元格标签的值从 tableView 传递到其他 View?

选择一个 TableView Cell 后,将数据传回 Swift 中的前一个 View Controller

在 UITableView 中传递和显示数据

将数据从 tableview 传递到另一个 tableview

用tableview重新加载uiviewcontroller的table view subobject的数据

将数据从 Tableview 传递到 Tableview 详细信息