2016-12-11 11 views
1

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

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

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

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

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

Спасибо!

+0

Я тоже это вижу, смогли ли вы решить? –

+1

Хорошо, я даже смог воспроизвести это в очень простом примерном проекте. Я зарегистрировал радар с идентификатором # 29853806 для этого, включил [этот образец проекта] (https://db.tt/YaQtByqx3E) и [это видеоролик об ошибке] (https://db.tt/MXD5v8sdEP). –

+0

Хм, у меня есть противоположная проблема: 'presentingViewController' отклоняется, когда я выхожу за пределы popover. – bio

ответ

0

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

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

  1. Добавить weakUIDocumentMenuViewController свойства вашего модального класса контроллера представления.
  2. Override -presentViewController:animated:completion: в вашем модальный класс, чтобы проверить и посмотреть, если контроллер представления будет представлен является UIDocumentMenuViewController, если так установить его в качестве значения для слабой собственности с шага 1.
  3. Override -dismissViewControllerAnimated:completion:, чтобы проверить, если ваш слабый недвижимость nil все же, если это не nil, а вашвашего модала - nil, то это означает, что WebKit пытается убрать ваш модальный, когда этого не должно быть. В этом случае вы можете избежать вызова super и продолжить его по-другому.

Вы также можете Swizzle WKFileUploadPanel «s _dismissDisplayAnimated: method быть более осторожными о своих собственных контроллерах зрения, но приходит со значительным количеством рисков.

1

У меня возникла та же проблема и, наконец, удалось найти обходной путь.

На мой взгляд, контроллер I переопределяет метод удаления управляемого объекта, если кнопка сохранения не была удалена, и это отлично сработало с UIImagePickerController.

В моем приложении используется UIDocumentPickerViewController, мой управляемый объект был удален при каждом вызове documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentAt url: URL), потому что это вызывает presentingViewController.dismiss.

Так что мое решение проверить из presentingViewController если presentedViewController является nil или не знать, если dismiss метод был назван UIDocumentPickerViewController или нет.

Так вот мой overriden 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) 
} 

Надеюсь, это вам поможет.