iOS 8 SDK:modal UIWebView和摄像头/图像选择器

iOS 8 SDK:modal UIWebView和摄像头/图像选择器,ios,objective-c,ios8,uiwebview,uiimagepickercontroller,Ios,Objective C,Ios8,Uiwebview,Uiimagepickercontroller,我发现,在为iOS 8编译(并在iOS 8中运行)时,UIWebView如果UIWebView位于以模式显示的视图控制器中,则无法显示摄像头/图像选择器。在视图控制器直接“挂起”于窗口rootViewController或从窗口推送视图控制器时,它可以正常工作 测试应用程序可以在上找到,但我将在下面描述它 我的测试应用程序(使用故事板构建,但实际应用程序不使用它们)有两个视图控制器(非原名为ViewController和ViewController2)ViewController包含在根视图控制

我发现,在为iOS 8编译(并在iOS 8中运行)时,
UIWebView
如果
UIWebView
位于以模式显示的视图控制器中,则无法显示摄像头/图像选择器。在视图控制器直接“挂起”于窗口
rootViewController
或从窗口推送视图控制器时,它可以正常工作

测试应用程序可以在上找到,但我将在下面描述它

我的测试应用程序(使用故事板构建,但实际应用程序不使用它们)有两个视图控制器(非原名为
ViewController
ViewController2
ViewController
包含在根视图控制器
UINavigationController
ViewController
包含一个
UIWebView
(工作正常)、一个“显示”(“按下”)
ViewController2
的按钮和一个以模式显示
ViewController2
UIBarButtonim
ViewController2
还有另一个
UIWebView
在“按下”时工作,但在“显示”时不工作

ViewController
ViewController2
都加载了:

- (void)viewDidLoad {
  [super viewDidLoad];

  [self.webView loadHTMLString:@"<input type=\"file\" accept=\"image/*;capture=camera\">" baseURL:nil];
}
我目前的理论是,
UIActionSheet
UIAlertController
的变化可能导致了这种情况,但很难证明这一点。我将与苹果公司合作,以防万一


是否有人发现了相同的情况和解决方法?

好的,这是我最终使用的解决方法。这是一个2分钟的变化,相当黑客,但工作如预期,避免了我们所有的错误。基本上,我没有以模式显示子视图控制器,而是将其设置为窗口的rootViewController,并保留对父控制器的引用。因此,我以前的位置(在父视图控制器中):

我现在有这个

view.window?.rootViewController = newController
在这两种情况下,父控制器都是
newController
的委托,这就是我保存引用的方式

newController.delegate = self
最后,在我关闭模式的委托回调中,我曾经有:

dismissViewControllerAnimated(true, completion: nil)
viewController.view.window?.rootViewController = self
我现在有这个:

dismissViewControllerAnimated(true, completion: nil)
viewController.view.window?.rootViewController = self
因此,我们得到了视图控制器完全接管屏幕的相同效果,然后在完成时产生其控制。但在本例中,它不是动画。我有一种感觉,在一些内置视图动画中,为控制器过渡设置动画并不困难


希望你已经按照苹果的建议使用委托模式来管理与模态控制器的通信,但如果你不这样做,我相信你可以使用任何数量的方法来保留引用并被调用。

我发现在iOS 8.0.2中,iPad似乎没有那个bug,但iPhone仍然有

但是,在包含uiwebview的视图控制器中重写以下内容

-(void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
检查是否有presentedViewController似乎可以工作

但需要检查副作用

#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

我遇到了类似的问题,我发现IOS中的UIWebView元素不支持html元素:

我不知道苹果为什么选择不支持这个重要的html元素,但我相信他们有自己的理由。(尽管此元素在IOS上的Safari上运行得非常好。)

在许多情况下,当用户在UIWebView中单击此类按钮时,将允许他们拍摄/选择照片。但是,IOS中的UIWebView无法在提交表单时将这样的文件附加到POST数据中


解决方案:要完成相同的任务,您可以在InterfaceBuilder中创建一个类似的表单,并使用一个按钮触发UIImagePickerController。然后,使用所有表单数据和图像创建一个HTTPPOST请求。这并不像听起来那么难,请查看下面的链接,获取一些完成任务的示例代码:

我的解决方案是基于控制器子-父层次结构创建具有自定义模态表示的自定义视图控制器。动画将是相同的,因此用户不会注意到差异

我对动画的建议:

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

它看起来与iOS7/8中的默认模式演示动画完全相同。

我在ios9上也有同样的问题。尝试添加ivar“\u标志”,然后使用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];
}

这对我来说很好

对我来说,我倾向于使用自定义的UINavigationController,以便多个视图可以共享相同的逻辑。因此,对于我的解决方法(Swift),这里是我在自定义NavigationController中添加的内容

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
    }
}

这意味着您可以使用WebView加载视图控制器,它们都将使用文件上载元素。

每次更改视图控制器时,我所做的是在根目录中转换目标视图

从第一视图控制器:

presentViewController(newController, animated: true, completion: nil)
let web = self.storyboard?.instantiateViewController(withIdentifier:"web") as! UINavigationController

view.window?.rootViewController = web
let first = self.storyboard?.instantiateViewController(withIdentifier: "reveal") as! SWRevealViewController
    present(first, animated: true, completion: nil)
这就是我如何将根传递给另一个,当回到第一个时,我做了这个

从web视图控制器:

presentViewController(newController, animated: true, completion: nil)
let web = self.storyboard?.instantiateViewController(withIdentifier:"web") as! UINavigationController

view.window?.rootViewController = web
let first = self.storyboard?.instantiateViewController(withIdentifier: "reveal") as! SWRevealViewController
    present(first, animated: true, completion: nil)
一切都很好,我可以显示模式选择照片从图书馆,拍照和其他一切

我不知道这是否是一个好的实践,但在模拟器和设备中运行良好


希望能有所帮助。

目前处境相同,尚未找到解决办法。我正在开发的应用程序在iOS 7中运行良好,但其性能与您在iOS 8中描述的一样。我悬赏这个问题,希望它能得到更多的关注。首先,输入文件在safari iOS 8上被破坏,它没有上传任何东西,这是一个bug,将在下次更新时修复。但我没有你的问题,当我点击输入文件按钮并在这里选择相同的类型(相机或照片库,没关系)时,我的应用程序就崩溃了。当webview位于显示为模态的控制器内时,就会出现问题。我想找出一个解决办法。仍然可以在iOS 7上运行,但不能在iOS 8上运行。我已经向AppleI请求了技术支持。我刚刚测试过,8.0.2上仍然存在漏洞,它可以在原始的view controller上运行