Попытка представить & lt; UIImagePickerController на UIViewController & gt; чей взгляд не находится в иерархии окон [дубликат]

35
задан computingfreak 9 March 2016 в 08:03
поделиться

7 ответов

Я обнаружил, что в iOS 8.0.2 у iPad, похоже, нет этой ошибки, но iPhone все еще делает.

Однако, переопределение в контроллере представления, содержащем uiwebview

-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion

И проверка того, что есть представленныйViewController, кажется, работает.

Но нужно проверить побочные эффекты

#import "UiWebViewVC.h"

@interface UiWebViewVC ()

@property (weak, nonatomic) IBOutlet UIWebView *uiwebview;

@end

@implementation UiWebViewVC

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSURL *url = [NSURL URLWithString:@"http://html5demos.com/file-api-simple"];

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    self.uiwebview.scalesPageToFit = YES;

    [self.uiwebview loadRequest:request];
}


-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
{
    if ( self.presentedViewController)
    {
        [super dismissViewControllerAnimated:flag completion:completion];
    }
}


@end
45
ответ дан seeinvisible 21 August 2018 в 10:18
поделиться
  • 1
    Кажется, это хороший способ обхода. Большое спасибо. Могу ли я спросить, как вы закончите с этим решением? – yonosoytu 8 October 2014 в 07:19
  • 2
    Uiwebview заставляет uialertcontroller быть представленным на контроллере uiwebviewview, чтобы показать камеру / существующий / отменить. Когда пользователь выбирает опцию, тогда uialertcontroller должен быть уволен и представлен uuiimagepickercontroller. Однако отклонение uialertcontroller, похоже, срабатывает дважды. В первый раз это нормально, потому что представленный контроллер = uialertcontroller, но во второй раз свойство presentationviewcontroller равно nil, и это приводит к тому, что killviewcontrolleranimated метод убивает веб-просмотр, который является проблемой, и теперь я тестирую этот случай – seeinvisible 8 October 2014 в 08:06
  • 3
    Это решило это для меня. Однако помните, если вы представляете свой пользовательский UIWebViewController (или WKWebViewController, если на то пошло) внутри UINavigationController, помните, что вместо этого нужно туда войти. Поэтому просто создайте подкласс UINavigationController и дамп вместо этого кода. – Baza207 8 October 2014 в 11:18
  • 4
    возможно. вам нужно будет вставить следующую строку в строке 724 в github.com/apache/cordova-plugin-inappbrowser/blob/master/src/… (void) завершение флажка cancelViewControllerAnimated: (BOOL) :( void (^) (void)) завершение {if (self.presentedViewController) {[super rejectViewControllerAnimated: завершение флага: завершение]; }} – seeinvisible 23 March 2015 в 18:02
  • 5
    @Riesling Эй, убедитесь, что вы добавили код в CDVInAppBrowserNavigationController, а не в CDVInAppBrowser. Вам не нужно будет добавлять атрибут Multiple, и он будет работать нормально. :) – Vishwani 30 March 2015 в 21:50

У меня такая же проблема на iOS 9. Попробуйте добавить ivar '_flag', а затем переопределите эти методы в контроллере view с помощью UIWebView

#pragma mark - Avoiding iOS bug

- (UIViewController *)presentingViewController {

    // Avoiding iOS bug. UIWebView with file input doesn't work in modal view controller

    if (_flagged) {
        return nil;
    } else {
       return [super presentingViewController];
    }
}

- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {

    // Avoiding iOS bug. UIWebView with file input doesn't work in modal view controller

    if ([viewControllerToPresent isKindOfClass:[UIDocumentMenuViewController class]]
    ||[viewControllerToPresent isKindOfClass:[UIImagePickerController class]]) {
        _flagged = YES;
    }

    [super presentViewController:viewControllerToPresent animated:flag completion:completion];
}

- (void)trueDismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion {

    // Avoiding iOS bug. UIWebView with file input doesn't work in modal view controller

    _flagged = NO;
    [self dismissViewControllerAnimated:flag completion:completion];
}

Это работает для меня отлично

6
ответ дан Artyom Devyatov 21 August 2018 в 10:18
поделиться
  • 1
    что trueDismissViewController? И добавить это в первый контроллер просмотра или контроллер Modal View? – esh 8 June 2016 в 07:00
  • 2
    trueDismissViewControllerAnimated:completion: - это то, что вы должны использовать в этом классе, когда вам нужно уволить, вместо вызова dismissViewControllerAnimated:completion:, который не будет работать. – Monkey Mike 13 April 2017 в 14:29

Хорошо, вот обходной путь, который я использовал. Это 2-минутное изменение, довольно взломанное, но работает как ожидалось и позволяет избежать ошибок, которые у всех нас есть. В принципе, вместо того, чтобы представлять контроллер дочернего представления по модулю, я устанавливаю его в rootViewController окна и сохраняю ссылку на родительский контроллер. Итак, где я использовал это (в контроллере родительского представления):

presentViewController(newController, animated: true, completion: nil)

Теперь у меня есть это

view.window?.rootViewController = newController

. В обоих случаях родительский контроллер newController s, который является тем, как я сохраняю ссылку.

newController.delegate = self

Наконец, где в моем обратном вызове делегата для закрытия модальности, где я использовал это:

dismissViewControllerAnimated(true, completion: nil)

У меня теперь есть это:

viewController.view.window?.rootViewController = self

. Таким образом, мы получаем тот же эффект, что и контроллер представления, полностью захватывающий экран, а затем дает свой контроль, когда это делается. Однако в этом случае он не анимирован. Я чувствую, что анимация перехода контроллера не будет очень сложной с некоторыми из встроенных анимаций просмотра.

Надеюсь, вы уже используете шаблон делегата для управления связью с модульным контроллером по рекомендации Apple , но если вы не уверены, вы можете использовать любое количество методов, которые сохраняют ссылку и получают обратный вызов.

0
ответ дан bloudermilk 21 August 2018 в 10:18
поделиться
  • 1
    как вы говорите, это обходной путь, вы знаете, что есть ошибка, когда представление является модальным, а затем вы делаете его контроллером корневого представления, а не представляете его модально. Но, как вы говорите, нет никакой возможности, и в случае, если вы находитесь в iPad, и вы не хотите представлять его на весь экран, с вашим обходным путем это невозможно. Вы можете просто нажать контроллер вида, и у вас будет тот же эффект, но с анимацией слайда – jcesarmobile 2 October 2014 в 11:28
  • 2
    @jcesarmobile да, не совсем доволен этим, но, по крайней мере, пусть мы будем распространять наше приложение. Отличная точка зрения на iPad. Мы только iPhone, поэтому я не подумал об этом. На самом деле, интересно, ошибка ли даже на iPad? – bloudermilk 2 October 2014 в 17:54
  • 3
    Это не похоже на андроид, но у меня эта проблема на iOS 8.1 с xamarin, и мне не удалось закодировать ваш обходной путь на xamarin :(. – GabLeRoux 14 November 2014 в 04:45

У меня была аналогичная проблема, и я обнаружил, что элементы UIWebView в IOS не поддерживают элемент html:

Я не уверен, почему Apple решила не поддерживать этот ВАЖНЫЙ элемент html, но Я уверен, что у них есть свои причины. (Несмотря на то, что этот элемент отлично работает на Safari в IOS.)

Во многих случаях, когда пользователь нажимает кнопку такого типа в UIWebView, он позволяет им выбирать / выбирать фотографию. ОДНАКО, UIWebView в IOS не имеет возможности прикреплять файлы, подобные этому, в данные POST при отправке формы.

Решение. Для выполнения той же задачи вы можете создать аналогичную форму в InterfaceBuilder с помощью кнопка, запускающая UIImagePickerController. Затем вы создаете запрос HTTP POST со всеми данными формы и изображением. Это не так сложно, как кажется, посмотрите ссылку ниже для некоторого примера кода, который выполняет задание: ios Загрузка изображения и текста с помощью HTTP POST

1
ответ дан Community 21 August 2018 в 10:18
поделиться

Для меня у меня обычно есть пользовательский UINavigationController, так что несколько представлений могут использовать одну и ту же логику. Поэтому для моего обходного пути (в Swift) вот что я ввел в свой пользовательский навигационный контроллер.

import UIKit

class NavigationController: UINavigationController {

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    override func dismissViewControllerAnimated(flag: Bool, completion: (() -> Void)?) {
        if let vc = self.presentedViewController {
            // don't bother dismissing if the view controller being presented is a doc/image picker
            if !vc.isKindOfClass(UIDocumentMenuViewController) || !vc.isKindOfClass(UIImagePickerController) {
                super.dismissViewControllerAnimated(flag, completion:completion)
            }
        }
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // make sure that the navigation controller can't be dismissed
        self.view.window?.rootViewController = self
    }
}

Это означает, что вы можете иметь множество контроллеров представлений с веб-просмотрами, и все они будут работать с загрузкой файла элемент.

1
ответ дан Jeremy JC Paul 21 August 2018 в 10:18
поделиться

Моим решением является создание настраиваемого контроллера представлений с настраиваемой модальной презентацией на основе иерархии дочерних элементов-контроллеров.

Мои предложения для анимации:

animateWithDuration:(animated ? 0.6 : 0.0)
                      delay:0.0
     usingSpringWithDamping:1.f
      initialSpringVelocity:0.6f
                    options:UIViewAnimationOptionCurveEaseOut

Он будет выглядеть точно так же, как анимация модального представления по умолчанию в iOS7 / 8.

0
ответ дан kelin 21 August 2018 в 10:18
поделиться

То, что я делал каждый раз, когда контроллер вида изменился, преобразует представление назначения в корневой каталог.

с контроллера первого вида:

let web = self.storyboard?.instantiateViewController(withIdentifier:"web") as! UINavigationController

view.window?.rootViewController = web

это то, как я передаю root / / g3]

let first = self.storyboard?.instantiateViewController(withIdentifier: "reveal") as! SWRevealViewController
    present(first, animated: true, completion: nil)

, и все в порядке, я могу показать модальный выбор фото из библиотеки, фотографировать и все остальное.

Я не знаю, хорошо ли это, но отлично работает в эмуляторе и устройстве.

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

0
ответ дан MSU_Bulldog 21 August 2018 в 10:18
поделиться