Мои данные задержались 1 раз, когда я хочу передать данные в своем табличном представлении и передать их другому контроллеру представления.
я использую подготовиться к переходу.
теперь, чтобы получить правильные данные, мне нужно вернуться к представлению таблицы и нажать ту же строку
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
}
}
}
он должен передавать данные в строке сразу после того, как я нажал строку
@vadian isee, так куда мне поместить асинхронность, чтобы отправлять правильные данные?
Подключите переход к контроллеру представления, получите данные в didSelect
и вызовите performSegue
вручную в блоке завершения.
можешь привести пример? @vadian
Мой последний комментарий является пример. Это довольно просто. Чтобы предоставить конкретное решение, код в вопросе слишком расплывчатый.
Вы должны реализовать tableVew(_:willSelectRowAt:)
метод UITableViewDelegate
в своем viewController и установить для свойства исправления значение выбранной строки.
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:)
, но этот метод работает после выполнения переходов и также вызывает проблему, с которой вы столкнулись.
Редактировать
Если вы считаете, что использование метода willSelectRowAt:
является неправильным использованием, вы можете установить источник перехода в свой viewController (вместо ячейки шаблона), установить идентификатор в раскадровке и вызвать его программно. как сказал @vadian
func tableView(_ tabelView: UITableView, didSelecRowAt indexPath: IndexPath){
correction = correctionList[indexPath.row]
performSegue(withIdentifier "mySegueIdentifier", sender: self)
}
На самом деле это не помогает, потому что задействована асинхронная задача. И вы злоупотребляете willSelectRowAt
.
Если вы имеете в виду выполнение перехода асинхронной задачей, эта операция будет выполнена после метода willSelect
. Также, если вы вернете nil в методе willSelectRow, переход не будет выполнен. Что касается неправильного использования, я не уверен в этом. Это может быть выбор в зависимости от использования во всем приложении.
спасибо за ответ, я работаю над вашим ответом, но я не знаю, что такое исправление: исправление!
Это экземпляр, который вы передаете в методе prepare(for:sender:)
. Я придумываю тип Correction
как тип вашей модели. Я думаю, вы использовали Dictionary
вместо модели класса.
Кроме того, вам не нужно использовать переход, вы можете создать экземпляр контроллера представления внутри метода didSelectRowAt с помощью следующего кода без prepareForSegue.
Обновлено: вы не указали, что это асинхронная задача. Итак, я использую 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.
На самом деле это не помогает, потому что задействована асинхронная задача.
спасибо за ответ @AtalayAsa, я думаю, что знаю, почему мои данные не передаются в первый раз, потому что я использую Alamofire для получения данных перед подготовкой перехода, но на самом деле система сначала запускает переход, а затем запускает alamofire, вот почему мои данные задержались. Теперь моя проблема в том, что я не понимаю, куда я должен поместить DispatchQueue.main.async {}, чтобы запустить alamofire до запуска segue.
Пожалуйста, @KlaudiusIvan. На самом деле, вы должны использовать DispatchQueue.main.async, когда вам нужно сделать вещи, связанные с пользовательским интерфейсом. Если мы вернемся к вашему вопросу, поэтому я поставил обработчик завершения. Когда ваш запрос к серверу выполнен, обработчик запускается немедленно, затем вызывается код внутри DispatchQueue.main.async, и это место, где вы помещаете свой код перехода.
Похоже на популярный всеми любимый асинхронная ловушка