В моем проекте я настроил UITableView, ячейки которого привязаны к сегменту, который переводит пользователя в другой ViewController, где данные из ячейки отображаются в деталях. Однако не все ячейки должны выполнять сегмент (например, запись, представленная в ячейке, недействительна и не должна отображаться, поэтому переход к контроллеру детализации не требуется).Отображение UIAlertViewController в файле shouldPerformSegue
Для решения этой задачи я использую shouldPerformSegue
метод в UIViewController в: (я предполагаю в следующем фрагменте, что вторая строка в таблице является тот, который не должен выполнять SEGUE)
override func shouldPerformSegue(withIdentifier identifier: String, sender: Any?) -> Bool {
guard let indexPath = tableView.indexPathForSelectedRow else {
return false
}
if indexPath.row == 1 {
let alert = UIAlertController(
title: "Invalid record",
message: "This record is malformed, can't display the data.",
preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "Okay :(", style: .default))
present(alert, animated: true, completion: nil)
return false
} else {
return true
}
}
Это приводит к некоторым странное поведение: всякий раз, когда я нажимаю вторую строку, предупреждение отображается только через секунду или два, иногда даже через пять секунд после нажатия, и иногда оно вообще не отображается, пока я не выполню некоторые другие действия пользовательского интерфейса, такие как прокрутка вида таблицы или нажатие еще раз.
После нескольких проб и ошибок я нашел решение: предупреждение будет отображаться сразу после нажатия на «ошибочную» ячейке, когда я заставляю его в основной поток:
DispatchQueue.main.async {
present(alert, animated: true, completion: nil)
}
Это нелогичное для меня, поскольку метод prepareForSegue
уже выполняется в основном потоке. Поэтому мой вопрос: откуда происходит неустойчивое поведение UIAlertController и нужно ли мне его отображать в основном потоке, или я делаю что-то неправильно?
Это не значит, что 'shouldPerformSegue' находится не в главной очереди, а скорее в том, что эта функция задействована в процессе segue, поэтому неплохо представить представление другого представления на этом этапе. Используя асинхронную отправку, вы позволяете завершить текущий процесс segue (или прерваться в этом случае) до появления предупреждения. Это правильное решение вашей проблемы. – Paulw11
Лично я проверял данные - перед выполнением segue - в методе tableView (_: didSelectRowAt :) delegate. –
Да, я согласен с Томом, я проверил бы строку в файле didSelectRowAt и, если потребуется, вызовет executeSegueWithIdentifier только при необходимости. – Scriptable