我是Swift的新手。我试图在两个视图控制器之间传递数据。当第二个视图控制器使用时,我从第一个视图控制器传递的值为nil。我不明白为什么会这样。
这是我在第一个视图控制器中的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
中的{p> 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
}
我的第二个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
。在调试器中,当视图控制器切换到selectedUserID
时,我可以看到填充了字符串的ChatLogController
。调用方法时,为什么selectedUserID
的值变量为nil?
我理解传递selectedUserID
和User
对象是多余的,我只是想看看问题是否是在类之间传递的String变量,但它保持为零。
任何帮助都会很棒!
修改 我正在使用segue在我的视图控制器之间切换
答案 0 :(得分:0)
您不需要实例化 ChatLogController 来传递数据,因为如果您正确设置 NavigationController ,那么他将为您实例化。
func setupChatLogControllerForUser(user: User) {
let chatLogController = ChatLogController()
chatLogController.selectedUserID = user.id!
chatLogController.user = user
}
因此,如果您想将数据传递给 ChatLogController ,您应该为此使用 prepareForSegue 方法。
我将提供一个基本示例,说明如何模仿此类功能:
这是结果:
这是我的故事板:
请注意, segue 的名称为 showDetail ,如图所示。
这是我的 TableViewController :
的代码当我触摸 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
}
}