UIDocumentPickerViewController отклоняет родительский контроллер представления
У меня есть WKWebView
в контроллере представления. Когда пользователь нажимает кнопку "Загрузить файл" (которая находится на указанной веб-странице), UIDocumentPickerViewController
всплывает. Это ожидается и совершенно необходимо, но:
Всякий раз, когда пользователь нажимает на любую кнопку ("Загрузить фото или видео", "Отмена"), UIDocumentPickerViewController
отклоняет себя И родительский контроллер представления, в котором это находится.
Я добавил символическую точку останова для [UIViewController dismissViewControllerAnimated:completion:]
и действительно видел, что -dismissViewController...
называется дважды. После первого увольнения UIDocumentPickerViewController
после второго - мой родительский контроллер вида.
Кстати, на iPad проблем нет, наверное потому что UIDocumentPickerViewController
представлен как поповер
Почему это происходит и что мне делать?
Спасибо!
3 ответа
Хорошо, я думаю, что нашел способ исправить это. WebKit с открытым исходным кодом, и вы можете видеть, что нарушающий класс WKFileUploadPanel
конкретно _dismissDisplayAnimated:
метод вызывается слишком агрессивно, непреднамеренно вызывая увольнение вашего контроллера представления. Во избежание этого вам нужно заблокировать звонки на -dismissViewControllerAnimated:completion:
которые приходят из WKFileUploadPanel
, что вы можете сделать, посмотрев вверх по стеку. Вот реализация, которая решает эту проблему.
Упомянутое выше решение не работает, потому что оно опирается на просмотр символов стека вызовов для определенного класса, который запутывается при работе на реальном устройстве. Вот другой подход, который я выбрал, чтобы решить эту проблему:
- Добавить
weak
UIDocumentMenuViewController
свойство вашего класса контроллера модального представления. - Override
-presentViewController:animated:completion:
в вашем модальном классе, чтобы проверить, является ли представляемый контроллер представленияUIDocumentMenuViewController
, если это так, установите его в качестве значения для вашего слабого свойства из шага 1. - Override
-dismissViewControllerAnimated:completion:
проверить, если ваша слабая собственностьnil
пока, если это не такnil
и ваш модалpresentedViewController
являетсяnil
тогда это означает, что WebKit пытается отклонить ваш мод, когда это не должно быть. Вы можете избежать звонкаsuper
в этом случае и продолжайте называть это иначе.
Вы также можете выпить WKFileUploadPanel
"s _dismissDisplayAnimated:
способ быть более осторожным в отношении собственных контроллеров представления, но это сопряжено со значительным риском.
Я столкнулся с той же проблемой и, наконец, сумел найти обходной путь.
На мой взгляд, контроллер я переопределить dismiss
метод для удаления управляемого объекта, если кнопка сохранения не была нажата, и это прекрасно работает с UIImagePickerController
,
Как из моего приложения использует UIDocumentPickerViewController
мой управляемый объект удалялся каждый раз documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL)
был вызван, потому что это вызывает presentingViewController.dismiss
,
Таким образом, мое решение состоит в том, чтобы проверить от presentingViewController
если presentedViewController
является nil
или не знать, если dismiss
метод был вызван UIDocumentPickerViewController
или нет.
Так вот мое переопределение dismiss
метод с моей точки зрения контроллера.
override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) {
if self.presentedViewController == nil {
// dismissed by the user
myDocument.delete()
} else {
// dismissed by the UIDocumentPickerViewController
// do nothing
}
super.dismiss(animated: flag, completion: completion)
}
Надеюсь, это поможет вам.
Я столкнулся с той же проблемой, это происходит при использовании средства выбора документов и происходит в версиях iOS ниже 11.4 . Используйте приведенный ниже код везде, где вы используете средство выбора документов. Из того, что я прочитал на разных форумах, есть проблема со средством выбора документов, и она была исправлена в более поздних версиях iOS .
Объявите слабое свойство средства выбора документов.
@property (weak, nonatomic) UIDocumentPickerViewController *_Nullable docPicker;
Затем реализуйте методы делегата контроллера представления:
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^ __nullable)(void))completion
{
if ([viewControllerToPresent isKindOfClass:[UIDocumentPickerViewController class]])
{
_docPicker = (UIDocumentPickerViewController*)viewControllerToPresent;
}
[super presentViewController:viewControllerToPresent animated:flag completion:completion];
}
- (void)dismissViewControllerAnimated:(BOOL)flag
completion:(void (^)(void))completion
{
if (_docPicker != nil && self.presentedViewController == nil)
{
}
else
{
[super dismissViewControllerAnimated:flag completion:completion];
}
}
Попробуйте это (работает):
navigationController?.dismiss(animated: true, completion: nil)