如何修复 prepare segue 的延迟数据?
How to fix delayed data on prepare segue?
当我想在 table 视图中传递数据并将其传递给另一个 viewcontroller
时,我的数据延迟了 1 次
我正在使用 prepare for segue。
现在,为了获得正确的数据,我需要返回 table 视图并按同一行
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toRequestCorrection"{
let destinationVC = segue.destination as! RequestCorrectionViewController
if let indexPath = tableView.indexPathForSelectedRow{
destinationVC.Shift = self.correction["Shift"].stringValue
destinationVC.LogDate = self.correction["LogDate"].stringValue
destinationVC.logIn = self.correction["ActualLogIn"].stringValue
destinationVC.logOut = self.correction["ActualLogOut"].stringValue
destinationVC.breakEnd = self.correction["ActualBreakEnd"].stringValue
destinationVC.breakStart = self.correction["ActualBreakStart"].stringValue
destinationVC.overTimeIn = self.correction["ActualOverTimeIn"].stringValue
destinationVC.overTimeOut = self.correction["ActualOverTimeOut"].stringValue
destinationVC.transactionStatusID = self.correction["TransactionStatusID"].intValue
}
}
}
它应该在我按下行后立即传递行上的数据
您应该在 viewController 中实施 UITableViewDelegate
的 tableVew(_:willSelectRowAt:)
方法,并将您的更正 属性 设置为选定行的值。
class YourSourceViewController: UITableViewDelegate{
var correction: Correction!
func tableView(_ tabelView: UITableView, willSelecRowAt indexPath: IndexPath) -> IndexPath?{
correction = correctionList[indexPath.row]
return indexPath
}
func prepare(for segue: UIStoryBoardSegue, sender: Any?){
//passing data to RequestCorrectionViewController.
//And also you don't need to check if indexPath is nil.
//Because this block will called only any row of tableView is selected.
}
}
另请注意,您可以在 tableView(_:didSelectRowAt:)
方法中做同样的事情,但此方法在执行 segues 后有效并导致您遇到的问题。
编辑
如果您认为使用 willSelectRowAt:
方法是一种误用,您可以将 segue 的源设置为 viewController(而不是模板单元格)并在 Storyboard 上设置标识符并以编程方式调用它。就像@vadian 说的
func tableView(_ tabelView: UITableView, didSelecRowAt indexPath: IndexPath){
correction = correctionList[indexPath.row]
performSegue(withIdentifier "mySegueIdentifier", sender: self)
}
此外,您不必使用 segue,您可以在没有 prepareForSegue 的情况下使用以下代码在 didSelectRowAt 方法中实例化视图控制器。
编辑:您没有指出这是一个异步任务。因此,我将 Alamofire 与完成处理程序一起使用。我想这对你有用。
typealias yourCompletionHandler = (Data?, _ message: String?, _ errorStatusCode: Int?) -> Void
func yourAsyncTask(handler: @escaping yourCompletionHandler) {
let parameters: [String: Any] = ["unitId": 4124]
let url = ""
Alamofire.request(url, method: .get, parameters: parameters)
.responseObject { (response: DataResponse<BaseListResponseParser<YourModel>>) in
switch response.result {
case .success:
if let result = response.result.value {
handler(result.listItems, nil, nil)
}
case .failure(let error):
print(error)
}
}
}
yourAsyncTask { [weak self] (yourModel, error, _) in
DispatchQueue.main.async {
guard let destination = UIStoryboard(name: "Main", bundle: nil)
.instantiateViewController(withIdentifier: "ViewControllerId") as? RequestCorrectionViewController else { return }
destination.Shift = yourModel.shift
navigationController?.pushViewController(destination, animated: true)
}
}
使用这种方式您不需要创建 segue 或 prepareForSegue 方法。
当我想在 table 视图中传递数据并将其传递给另一个 viewcontroller
时,我的数据延迟了 1 次我正在使用 prepare for segue。
现在,为了获得正确的数据,我需要返回 table 视图并按同一行
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "toRequestCorrection"{
let destinationVC = segue.destination as! RequestCorrectionViewController
if let indexPath = tableView.indexPathForSelectedRow{
destinationVC.Shift = self.correction["Shift"].stringValue
destinationVC.LogDate = self.correction["LogDate"].stringValue
destinationVC.logIn = self.correction["ActualLogIn"].stringValue
destinationVC.logOut = self.correction["ActualLogOut"].stringValue
destinationVC.breakEnd = self.correction["ActualBreakEnd"].stringValue
destinationVC.breakStart = self.correction["ActualBreakStart"].stringValue
destinationVC.overTimeIn = self.correction["ActualOverTimeIn"].stringValue
destinationVC.overTimeOut = self.correction["ActualOverTimeOut"].stringValue
destinationVC.transactionStatusID = self.correction["TransactionStatusID"].intValue
}
}
}
它应该在我按下行后立即传递行上的数据
您应该在 viewController 中实施 UITableViewDelegate
的 tableVew(_:willSelectRowAt:)
方法,并将您的更正 属性 设置为选定行的值。
class YourSourceViewController: UITableViewDelegate{
var correction: Correction!
func tableView(_ tabelView: UITableView, willSelecRowAt indexPath: IndexPath) -> IndexPath?{
correction = correctionList[indexPath.row]
return indexPath
}
func prepare(for segue: UIStoryBoardSegue, sender: Any?){
//passing data to RequestCorrectionViewController.
//And also you don't need to check if indexPath is nil.
//Because this block will called only any row of tableView is selected.
}
}
另请注意,您可以在 tableView(_:didSelectRowAt:)
方法中做同样的事情,但此方法在执行 segues 后有效并导致您遇到的问题。
编辑
如果您认为使用 willSelectRowAt:
方法是一种误用,您可以将 segue 的源设置为 viewController(而不是模板单元格)并在 Storyboard 上设置标识符并以编程方式调用它。就像@vadian 说的
func tableView(_ tabelView: UITableView, didSelecRowAt indexPath: IndexPath){
correction = correctionList[indexPath.row]
performSegue(withIdentifier "mySegueIdentifier", sender: self)
}
此外,您不必使用 segue,您可以在没有 prepareForSegue 的情况下使用以下代码在 didSelectRowAt 方法中实例化视图控制器。
编辑:您没有指出这是一个异步任务。因此,我将 Alamofire 与完成处理程序一起使用。我想这对你有用。
typealias yourCompletionHandler = (Data?, _ message: String?, _ errorStatusCode: Int?) -> Void
func yourAsyncTask(handler: @escaping yourCompletionHandler) {
let parameters: [String: Any] = ["unitId": 4124]
let url = ""
Alamofire.request(url, method: .get, parameters: parameters)
.responseObject { (response: DataResponse<BaseListResponseParser<YourModel>>) in
switch response.result {
case .success:
if let result = response.result.value {
handler(result.listItems, nil, nil)
}
case .failure(let error):
print(error)
}
}
}
yourAsyncTask { [weak self] (yourModel, error, _) in
DispatchQueue.main.async {
guard let destination = UIStoryboard(name: "Main", bundle: nil)
.instantiateViewController(withIdentifier: "ViewControllerId") as? RequestCorrectionViewController else { return }
destination.Shift = yourModel.shift
navigationController?.pushViewController(destination, animated: true)
}
}
使用这种方式您不需要创建 segue 或 prepareForSegue 方法。