如何修复 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 中实施 UITableViewDelegatetableVew(_: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 方法。