Задержка при представлении модального контроллера
У меня есть приложение на основе панели вкладок. На всех 5 вкладках есть контроллеры навигации с примерами настройки пользовательского контроллера просмотра в качестве контроллеров корневого представления. Это очень просто. Пара этих контроллеров представлений содержит представления таблиц. Я хочу показать пользователю modal view, когда они выбирают строку в представлении таблицы. Способ (соответствующая часть) didSelectRowAtIndexPath выглядит следующим образом:
SampleSelectorViewController *sampleVC = [[SampleSelectorViewController alloc] init];
[self presentViewController:sampleVC animated:YES completion:NULL];
Появится контроллер модального просмотра, но он появится после очень заметной задержки. Время от времени даже требуется, чтобы пользователь второй раз нажал на строку. Несколько вещей, которые я уже проверил:
- Вид таблицы didSelectRowAtIndexPath метод вызывается, когда пользователь удаляет строку
- Метод didSelectRowAtIndexPath не содержит блокирующих вызовов. Выполняются сетевые операции, и установка контроллера модального просмотра не требует какой-либо интенсивной обработки. Отображаемые данные являются статическими.
- Если я нажму новый контроллер просмотра в стек навигации (все остальное останется точно таким же), он будет вести себя отлично без каких-либо задержек. Только при условии, что встречаются задержки.
Любые идеи/предложения?
Ответы
Ответ 1
Кажется, вызов presentViewController:animated:completion
изнутри tableView:didSelectRowAtIndexPath:
проблематичен. Трудно найти все, что выделяется при использовании Time Profiler in Instruments. Иногда мой модальный вид появляется менее чем за секунду, а иногда и занимает 4 с или даже 9 секунд.
Я думаю, что это связано с базовым UIPresentationController
и макетом, что является одной из немногих вещей, которые я вижу при выборе области времени между нажатием на строку и просмотром модальной презентации в Time Profiler.
Радар существует, описывая эту проблему: http://openradar.appspot.com/19563577
Обходной проста, но неудовлетворителен:. Немного задержать презентацию, чтобы избежать любой спорного поведения вызывает замедление
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:nav animated:YES completion:nil];
});
Ответ 2
Вы должны отображать это модально из вашего корневого vc (например: customTabBarRootViewController).
сохраните ссылку и используйте контрольный контроллер для ее отображения.
Ответ 3
Я предполагаю, что вы также устанавливаете ячейку selectionStyle в UITableViewCellSelectionStyleNone
. Я изменяю на UITableViewCellSelectionStyleDefault
и он отлично работает.
Ответ 4
У меня также была эта странная задержка, когда представление из tableView:didSelectRowAtIndexPath:
выглядит как ошибка Apple.
Это решение, похоже, работает хорошо.
CFRunLoopWakeUp(CFRunLoopGetCurrent()); // Fixes a bug where the main thread may be asleep, especially when using UITableViewCellSelectionStyleNone
Ответ 5
Swift 4: вы можете использовать как показано ниже.
DispatchQueue.main.async {
let popUpVc = Utilities.viewController(name: "TwoBtnPopUpViewController", onStoryboard: "Login") as? TwoBtnPopUpViewController
self.present(popUpVc!, animated: true, completion: nil)
}
Меня устраивает.
Ответ 6
Если вы вызываете present (: animated: завершение :) в tableView (: didSelectRowAt :), selectionStyle ==.none для выбранной ячейки табличного представления, и вы получили это странное поведение, то попробуйте вызвать tableView.deselectRow(at: animated :) перед любыми операциями в tableView (_: didSelectRowAt :).
Это помогло?
Ответ 7
Решение в Swift 3
В SampleSelectorViewController (представленный контроллер представления) используйте приведенный ниже код
DispatchQueue.global(qos: .background).async {
// Write your code
}
Ответ 8
Общая проблема с этим поведением заключается в следующем:
один устанавливает selectionStyle =.none
для ячейки в tableView (кажется, что он не зависит от подклассов UITableViewController
как было написано на http://openradar.appspot.com/19563577) и использует метод делегата
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
анимация отмены выбора
tableView.deselectRow(at: indexPath, animated: true)
что подразумевает анимацию для неанимационной ячейки.
В этом случае последующее представление контроллера представления имеет задержку.
Существует несколько обходных решений, в том числе dispatch_async
для основного потока, но лучше не вызывать deselectRow
даже без анимации для невыбираемых ячеек в вашем коде.
Ответ 9
Согласно комментарию @Y.Bonafons, в Swift вы можете попробовать вот так (для Swift 4.x и 5.0)
DispatchQueue.main.async {
self.showAction() //Show what you need to present
}