这是我的数据库结构:
我正在使用一个带闭包的函数,执行两个完成 block 并将数据存储在两个单独的数组中。获得数据后,我想将数据传递到下一个 View Controller 到不同的变量中,但我得到的是两个数组的相同值。
@IBAction func GoToAnswerPage(_ sender: Any) {
self.getData(refe:JoinCodeTextField.text!) { (array) in
self.performSegue(withIdentifier:"JoinToAnswerPage",sender:array)
}
}
func getData(refe: String, completion: @escaping (([Any]) -> ())) {
var questionArray = [Any]()
var answerArray = [Any]()
let ref = Database.database().reference(fromURL: "https://pollapp-30419.firebaseio.com/").child("Questions/\(refe)/")
ref.child("Question_And_Options").observeSingleEvent(of: .value,with: { snapshot in
let enumerator = snapshot.children
while let rest = enumerator.nextObject() as? DataSnapshot, let value = rest.value{
questionArray.append(value)
}
completion(questionArray)
})
ref.child("Answer_Key").observeSingleEvent(of: .value,with: { snapshot in
let enumerator = snapshot.children
while let rest = enumerator.nextObject() as? DataSnapshot, let value = rest.value{
answerArray.append(value)
}
completion(answerArray)
})
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let joinViewController = segue.destination as? JoinAnswerViewController
else {
return
}
joinViewController.answers = sender as! [String]
joinViewController.options = sender as! [String]
}
在下一个 View Controller 上。
var options = [Any]()
var answers = [Any]()
这是我得到的输出:
answers-["Test Q-1", "Test A-1", "Test A-2"]
questions-["Test Q-1", "Test A-1", "Test A-2"]
answers-["Test A-1"]
questions-["Test A-1"]
相反,我应该得到:
questions-["Test Q-1", "Test A-1", "Test A-2"]
answers-["Test A-1"]
最佳答案
您的完成处理程序将被调用两次,一次用于“答案”,一次用于“问题”。它们可以以任意顺序出现,因此您应该在完成时传递一个额外的 type
以了解您收到了哪个。使用 [String : [Any]]
字典收集两个数组,并在收到两个数组并存储后调用 self.performSegue(withIdentifier:sender:)
它们在字典 arrays
中。
在 prepare(for:sender:)
中解压 sender
字典并赋值:
@IBAction func GoToAnswerPage(_ sender: Any) {
var arrays = [String : [Any]]()
self.getData(refe: JoinCodeTextField.text!) { (array, type) in
arrays[type] = array
if arrays.count == 2 {
self.performSegue(withIdentifier:"JoinToAnswerPage",sender: arrays)
}
}
}
func getData(refe: String, completion: @escaping (([Any], String) -> ())) {
var questionArray = [Any]()
var answerArray = [Any]()
let ref = Database.database().reference(fromURL: "https://pollapp-30419.firebaseio.com/").child("Questions/\(refe)/")
ref.child("Question_And_Options").observeSingleEvent(of: .value,with: { snapshot in
let enumerator = snapshot.children
while let rest = enumerator.nextObject() as? DataSnapshot, let value = rest.value{
questionArray.append(value)
}
completion(questionArray, "question")
})
ref.child("Answer_Key").observeSingleEvent(of: .value,with: { snapshot in
let enumerator = snapshot.children
while let rest = enumerator.nextObject() as? DataSnapshot, let value = rest.value{
answerArray.append(value)
}
completion(answerArray, "answer")
})
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let joinViewController = segue.destination as? JoinAnswerViewController
else {
return
}
guard let arrays = sender as? [String : [Any]],
let answers = arrays["answer"] as? [String],
let questions = arrays["question"] as? [String]
else { return }
joinViewController.answers = answers
joinViewController.options = questions
}
注意:当用户按下按钮时,他们应该立即得到响应。由于您是从网络加载数据,因此可能会有延迟,使用户怀疑是否发生了什么。最好将 JoinCodeTextField.text!
传递给 JoinAnswerViewController
并让它加载问题/答案数据。 JoinAnswerViewController
可以在数据加载时显示一个 UIActivityIndicatorView
(微调器),让用户知道数据即将到来。拥有两个数组后,您可以设置 JoinAnswerViewController
。
关于swift - 如何在单个函数中执行两个完成 block 并将完成 block 的数据传递给下一个 View Controller ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57367359/