UIDocumentPickerViewController отклоняет родительский контроллер представления

У меня есть WKWebView в контроллере представления. Когда пользователь нажимает кнопку "Загрузить файл" (которая находится на указанной веб-странице), UIDocumentPickerViewController всплывает. Это ожидается и совершенно необходимо, но:

Всякий раз, когда пользователь нажимает на любую кнопку ("Загрузить фото или видео", "Отмена"), UIDocumentPickerViewController отклоняет себя И родительский контроллер представления, в котором это находится.

Я добавил символическую точку останова для [UIViewController dismissViewControllerAnimated:completion:] и действительно видел, что -dismissViewController... называется дважды. После первого увольнения UIDocumentPickerViewControllerпосле второго - мой родительский контроллер вида.

Кстати, на iPad проблем нет, наверное потому что UIDocumentPickerViewController представлен как поповер

Почему это происходит и что мне делать?

Спасибо!

3 ответа

Хорошо, я думаю, что нашел способ исправить это. WebKit с открытым исходным кодом, и вы можете видеть, что нарушающий класс WKFileUploadPanel конкретно _dismissDisplayAnimated: метод вызывается слишком агрессивно, непреднамеренно вызывая увольнение вашего контроллера представления. Во избежание этого вам нужно заблокировать звонки на -dismissViewControllerAnimated:completion: которые приходят из WKFileUploadPanel , что вы можете сделать, посмотрев вверх по стеку. Вот реализация, которая решает эту проблему.

Упомянутое выше решение не работает, потому что оно опирается на просмотр символов стека вызовов для определенного класса, который запутывается при работе на реальном устройстве. Вот другой подход, который я выбрал, чтобы решить эту проблему:

  1. Добавить weakUIDocumentMenuViewController свойство вашего класса контроллера модального представления.
  2. Override -presentViewController:animated:completion: в вашем модальном классе, чтобы проверить, является ли представляемый контроллер представления UIDocumentMenuViewController, если это так, установите его в качестве значения для вашего слабого свойства из шага 1.
  3. 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)
Другие вопросы по тегам