`UIViewController.present` обработчик завершения вызывается немедленно
Я использую Xcode 10 Beta 6, так что это может быть просто ошибкой.
Я пытаюсь представить вид контроллера (colorPickerController
) как поповер В этом контроллере представления я смогу установить некоторые свойства, которые я хочу прочитать, когда всплывающее окно отклонено.
Вот код:
В строках 93...97 я определяю обработчик завершения.
В строке 99 я представляю colorPickerController
Модально, включая обработчик завершения.
При запуске кода контроллер палитры цветов был успешно показан во всплывающем окне. Но когда я постучал за пределы поповера (чтобы от него отказаться), обратный вызов не был вызван.
Я думал, может быть UIPopoverPresentationController
не отклоняет "нормально", поэтому я попытался вручную закрыть поповер до того, как он сам это сделает, вызвав dismiss
в popoverPresentationControllerShouldDismissPopover
(строка 110).
Теперь это все еще не работает, поэтому я установил точку останова, как показано на рисунке, чтобы проверить, вызывается ли метод делегата.
Именно тогда я заметил, что при запуске приложения обработчик завершения вызывается правильно, когда появляется всплывающее окно, а не когда оно закрывается.
Я входил Completion handler was called.
в консоли, даже не достигнув точки останова.
Как это возможно?
2 ответа
То, как ваш код в вашем вопросе, ваш updateColor
Закрытие вызывается только тогда, когда заканчивается презентационная анимация, а не когда представляемый вами контроллер представления выполняет то, что ему нужно.
Смотрите документы для UIViewController.present(_:animated:completion:)
: https://developer.apple.com/documentation/uikit/uiviewcontroller/1621380-present
завершение
Блок для выполнения после окончания презентации. Этот блок не имеет возвращаемого значения и не принимает параметров. Вы можете указать
nil
для этого параметра.
Обратите внимание на "после окончания презентации" (выделено мной). Это означает, что замыкание будет выполнено буквально сразу после 0,2 секунды времени, которое требуется для анимации представления нового контроллера представления вверх от нижней части экрана (или сколько бы времени это ни заняло и любым другим способом, если вы делаете какую-то фантазию пользовательская презентация анимации).
Чтобы получить обратный вызов, когда ваш новый контроллер представления будет выполнять все, что ему нужно, подкласс UIViewController
(позвони, скажи, ColorPickerViewController
) и использовать какое-либо делегирование, чтобы уведомить ваш текущий контроллер вида об отмене контроллера представления средства выбора цвета (и, предположительно, сказать ему, какой цвет был выбран).
@TylerTheCompiler верный, завершение, которое вы передаете, запускается после завершения анимации. Чтобы выполнить то, что вы хотите, вот что я рекомендую:
1) Создайте подкласс UIViewController и создайте пользовательский тип.
2) Добавьте свойство в новый класс типа:
var functionToFinish: (() -> Void)
3) Измените определение цвета обновления:
let updateColor: (() -> Void) = ...
3a) Вставьте остальную часть вашей функции для...
4) В строке 98 напишите:
colorPickerController.functionToFinish = updateColor
5) Теперь внутри подклассного контроллера вы можете вызывать эту функцию из события viewDidDisappear.