Swift 视图控制器之间传输的数据保持为空

Swift Transferred Data between View Controllers stays empty

我是 Swift 的新手。我正在尝试在两个视图控制器之间传递数据。当第二个视图控制器使用时,我从第一个视图控制器传递的值是 nil。我不明白为什么会这样。

这是我在第一个视图控制器中的 tableView 函数调用。它获取所选 table 单元格的用户信息。

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

    let user = User()


    if(messages.count > 0) {
        let message = self.messages[indexPath.row]

        guard let chatPartnerID = message.chatPartnerID() else {
            return
        }


        let ref = FIRDatabase.database().reference().child("users").child(chatPartnerID)
        ref.observeSingleEventOfType(.Value, withBlock: { (snapshot) in

            guard let dictionary = snapshot.value as? [String: AnyObject]
                else {
                    return
            }

            user.id = chatPartnerID
            user.setValuesForKeysWithDictionary(dictionary)
            self.setupChatLogControllerForUser(user)

            }, withCancelBlock: nil)
    }else {
        let user = users[indexPath.row]
        self.setupChatLogControllerForUser(user)
    }


}

UserNSObject 中,我这样声明:

class User: NSObject {

  var id: String?
  var name: String?
  var email: String?
  var profileImageUrl: String?
}

第一个视图控制器中的 setupChatLogControllerForUser(user) 方法接收在 tableView 方法中给出的用户参数并传递给第二个视图控制器 (ChatLogController),如下所示:

 func setupChatLogControllerForUser(user: User) {
    let chatLogController = ChatLogController()
    chatLogController.selectedUserID = user.id!
    chatLogController.user = user
}

我的第二个 View Controller 方法用这个接收数据:

var selectedUserID = String()
var user = User()

第二个视图控制器也有一个 handleSend 方法,它通过 IBAction 链接到我故事板上的一个按钮。

func handleSend() {

    let ref = FIRDatabase.database().reference().child("messages")
    let childRef = ref.childByAutoId()
    let toID = self.selectedUserID
    let fromID = FIRAuth.auth()!.currentUser!.uid
    let timestamp: NSNumber = Int(NSDate().timeIntervalSince1970)

    let values = ["text": messageInputField.text!, "toID": toID, "fromID": fromID, "timestamp": timestamp]
    childRef.updateChildValues(values) { (error, ref) in

        if error != nil {
            print(error)
            return
        }

        let userMessagesRef = FIRDatabase.database().reference().child("userMessages").child(fromID)

        let messageID = childRef.key
        userMessagesRef.updateChildValues([messageID: 1])

        let recipientUserMessagesRef = FIRDatabase.database().reference().child("userMessages").child(toID)
        recipientUserMessagesRef.updateChildValues([messageID: 1])

    }

}

这个方法就是出问题的地方。我设置 toID 等于 selectedUserID。在调试器中,当视图控制器转到 ChatLogController 时,我可以看到 selectedUserID 填充了一个字符串。为什么调用方法时selectedUserID变量的值是nil?

我知道传入 selectedUserIDUser 对象是多余的,我只是想看看问题是否出在 类 之间传递的 String 变量上, 但它保持为零。

任何帮助都会很棒!

编辑: 我正在使用 segue 在我的视图控制器之间切换

你不需要实例化ChatLogController来传递数据,因为如果你正确设置了NavigationController,那么他会为你实例化。

func setupChatLogControllerForUser(user: User) {
    let chatLogController = ChatLogController()
    chatLogController.selectedUserID = user.id!
    chatLogController.user = user
}

因此,如果您想将数据传递给 ChatLogController,您应该为此目的使用 prepareForSegue 方法。


我将提供一个基本示例,您可以如何模仿此类功能:

这是结果:


这是我的故事板:

请注意,segue 的名称是 showDetail,如图所示。


这是我的表ViewController的代码:

当我触摸 TableViewController 上的单元格时,调用 didSelectRowAtIndexPath 方法,然后我访问该单元格选择并将值设置为 dataToSend 变量,最后我调用 performSegueWithIdentifier 以导航到 ViewController.

但就在它进入 ViewController 之前,prepareForSegue 方法被调用,所以你有机会在这里通过任何ViewController 期望的变量,在这种情况下,我将 dataToSend 传递给 ViewController 的 dataSent 变量。

class TableViewController: UITableViewController {

  var dataToSend = ""

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

  override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
    let cell = tableView.cellForRowAtIndexPath(indexPath)

    dataToSend = cell!.textLabel!.text!

    performSegueWithIdentifier("showDetail", sender: nil)
  }

  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
    if segue.identifier == "showDetail" {
      if let viewController = segue.destinationViewController as? ViewController {
        viewController.dataSent = dataToSend
      }
    }
  }

}

这是 ViewController 的代码:

然后我可以在标签中显示值。

class ViewController: UIViewController {
  @IBOutlet weak var label: UILabel!

  var dataSent = String()

  override func viewDidLoad() {
    super.viewDidLoad()

    label.text = dataSent
  }

}