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

Ios 视图控制器之间的Swift传输数据保持为空,ios,swift,uitableview,transfer,Ios,Swift,Uitableview,Transfer,我不熟悉斯威夫特。我试图在两个视图控制器之间传递数据。当第二个视图控制器使用时,我从第一个视图控制器传递的值为零。我不明白为什么会这样 这是我在第一个视图控制器中的tableView函数调用。它获取所选表格单元格的用户信息 override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) { let user = User() if(messages

我不熟悉斯威夫特。我试图在两个视图控制器之间传递数据。当第二个视图控制器使用时,我从第一个视图控制器传递的值为零。我不明白为什么会这样

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

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


}
User
NSObject
中,我这样声明:

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
}
我的第二个视图控制器方法通过以下方式接收数据:

var selectedUserID = String()
var user = User()
第二个视图控制器还有一个
handleSend
方法,该方法通过
iAction
链接到我的故事板上的一个按钮

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

我知道传入
selectedUserID
User
对象是多余的,我只是想看看在类之间传递字符串变量是否有问题,但它保持为零

任何帮助都会很棒

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

您不需要实例化聊天记录控制器来传递数据,因为如果您正确设置了导航控制器,那么他将为您实例化

func setupChatLogControllerForUser(user: User) {
    let chatLogController = ChatLogController()
    chatLogController.selectedUserID = user.id!
    chatLogController.user = user
}
因此,如果您想将数据传递给ChatLogController,您应该为此使用prepareforsgue方法


我将提供一个基本示例,说明如何模拟此类功能:

这是结果


这是我的故事板:

请注意,序列的名称为showdeail,如图所示


这是我的TableViewController的代码:

当我触摸TableViewController上的单元格时,会调用didSelectRowAtIndexPath方法,然后我访问所选单元格并将值设置为dataToSend变量,最后我调用PerformsgueWithIdentifier以导航到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
      }
    }
  }

}

这是视图控制器的代码:

因为我可以在标签中显示值

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

  var dataSent = String()

  override func viewDidLoad() {
    super.viewDidLoad()

    label.text = dataSent
  }

}

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

func setupChatLogControllerForUser(user: User) {
    let chatLogController = ChatLogController()
    chatLogController.selectedUserID = user.id!
    chatLogController.user = user
}
因此,如果您想将数据传递给ChatLogController,您应该为此使用prepareforsgue方法


我将提供一个基本示例,说明如何模拟此类功能:

这是结果


这是我的故事板:

请注意,序列的名称为showdeail,如图所示


这是我的TableViewController的代码:

当我触摸TableViewController上的单元格时,会调用didSelectRowAtIndexPath方法,然后我访问所选单元格并将值设置为dataToSend变量,最后我调用PerformsgueWithIdentifier以导航到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
      }
    }
  }

}

这是视图控制器的代码:

因为我可以在标签中显示值

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

  var dataSent = String()

  override func viewDidLoad() {
    super.viewDidLoad()

    label.text = dataSent
  }

}

如何从你的第一个vc转到第二个vc?segue或编程?您应该执行segue而不是新的ChatLogController()。问题是
ChatLogController()
。这是一个新的空实例,而不是故事板中预期的控制器。@ivy_p您使用的是segue还是编程方式?@GaneshKumar我使用的是segue如何从第一个vc移动到第二个vc?segue或编程?您应该执行segue而不是新的ChatLogController()。问题是
ChatLogController()
。这是一个新的空实例,而不是故事板中预期的控制器。@ivy_p您是在使用segue还是以编程方式使用?@GaneshKumar我在使用segue非常感谢您的清晰解释,它成功了!非常感谢您的清晰解释,它成功了!