Phonegap/Cordova camera.getPicture放置在子视图中时行为异常

Phonegap/Cordova camera.getPicture放置在子视图中时行为异常,cordova,xamarin.ios,cordova-2.0.0,Cordova,Xamarin.ios,Cordova 2.0.0,我正在创建一个应用程序,其中我使用Cordova Cleaver作为应用程序中的子视图。根据应用程序的状态,我们可能在视图的底部有一个工具栏。当我们隐藏工具栏时,我们会增加Cordova视图的大小,以便它占据整个视图(减去顶部的状态栏)。之所以这样做,是因为我们可以重用Webview来显示任意位置的内容,如果这些页面支持cordova本机功能,特别是如果它们实现了我们的应用程序API,我们可以提供cordova本机功能 完全公开,我使用MonoTouch是因为我们希望跨平台使用一些大型复杂的业务

我正在创建一个应用程序,其中我使用Cordova Cleaver作为应用程序中的子视图。根据应用程序的状态,我们可能在视图的底部有一个工具栏。当我们隐藏工具栏时,我们会增加Cordova视图的大小,以便它占据整个视图(减去顶部的状态栏)。之所以这样做,是因为我们可以重用Webview来显示任意位置的内容,如果这些页面支持cordova本机功能,特别是如果它们实现了我们的应用程序API,我们可以提供cordova本机功能

完全公开,我使用MonoTouch是因为我们希望跨平台使用一些大型复杂的业务逻辑,但就视图以及它们的创建方式而言,我只使用iOS库(使用MonoTouch C#wrappers),但这不应该引起问题

为了清楚起见,我们有AppViewController,它包含一个工具栏和一个WebViewController(CDVViewController的子类)。工具栏用于允许本机应用程序中的某些功能,如添加收藏夹或返回应用程序主页面

这似乎很有效,但在一个具体案例中存在问题(至少到目前为止)。当我们运行Cordova的camera.getPicture命令时,状态栏是隐藏的,但摄影机视图似乎仍然放置在顶部,状态栏空间位于顶部,从而切断了“取消”按钮。在iPhone上,如果你点击相机按钮或取消,它似乎也会调用此视图下方的工具栏按钮

为了克服这个问题,我将CDVCamera子类化,并覆盖了TakePicture、DidCancelImagePicker、DidFinishPickingMediaWithInfo、DidFinishPickingImage方法,这样当我们开始拍照任务时,它将隐藏状态栏和工具栏,并通过关联调整WebViewController视图和WebView的大小,因此,他们实际上是唯一的观点。这是可行的,但我们开始遇到另一个相关的bug。摄影机拾取器在第一次显示时会显示得非常好,但是如果我们取消拾取器,并重新拾取(在风景中),它会偶尔在右侧显示一个黑色的大区域。在这种状态下,我们可以任意旋转它,它仍然显示为正方形。在肖像画中取消和打开似乎100%成功,但风景画似乎有不同的可靠性。点击此视图中的摄影机视图似乎可以拍摄照片,但正如您所看到的,这就好像摄影机选择器放大了图像的一部分

我试着将我的努力建立在Holly Schinsky的基础上,但也许我做了一些错误的事情,缺少了一些配置,或者有更好的方法我应该这样做

非常感谢您的帮助


其他有用信息:

  • Cordova 2.4.0是我目前正在使用的,但尝试了2.3.0和2.7.0,问题似乎没有任何不同

    • 在这个问题上讨论了几个星期后,今天我找到了解决方案。我不确定是否有人会需要它,但如果他们需要,我遇到的问题是,我正在获取Cordova ViewController的视图,并将其添加到更大的应用程序ViewController的视图中。我缺少的是使用
      AddChildViewController
      将我的Cordova ViewController添加为子视图控制器。通过将Cordova ViewController作为子级,它将转发所需的旋转和其他应用程序事件。现在每件事都很完美。但愿我能在几周前找到这个

      对于其他遇到类似问题的用户,如果您像我一样正在创建一个新的Cordova ViewController,并将其嵌入到您自己的视图控制器中,类似的操作应该会起作用

      这是涉及的mono的子集(我使用xib作为接口)

      我希望这有帮助

      基于Jason G的代码,我尝试在Objective-C中编写我的代码。如果发现错误,请编辑此代码

      - (void)viewDidLoad
      {
          webView = [CDVViewController new];
      
          // If you have a start page you'd like to load, enter it here
          // Or leave it commented to use what's configured in the config.xml
          // webView.startPage = "";
      
          [self addChildViewController:webView];
      
          [self.view addSubview:webView.view];
      }
      

      请注意,这并不是您可能需要的全部代码。您可能还需要为
      self.View
      设置视图框。这里的关键是
      addChildViewController
      ,默认情况下,它会将重要的应用程序事件转发到子ViewController上。

      是的,我的代码就是这样的,我几乎让它在旧的子视图上打开一个新的子视图,当我需要刷新时,我找不到任何其他选项,然后关闭子视图并重新调用它,我想它会正常工作。但我想冲出的主要问题是相机打开时的偏移量

      我的H


      为什么要嵌入Cordova camera控件而不是使用本机camera API(或Xamarin.Mobile API)?这种方法能给你带来什么?长话短说,我们已经有了一个相当成熟的基于HTML5的应用程序,但要启用一些特定的用例,我们需要能够将其包装到一个本机应用程序中以提供该功能。Cordova允许我们从基于HTML5的应用程序中的javascript调用摄像头。您能否显示您如何使用Cordova viewController实现AddChildViewController的代码,我的摄像头也有同样的问题。@JasonG:您是否将Cordova视图作为主视图控制器中的子视图加载?
      - (void)viewDidLoad
      {
          webView = [CDVViewController new];
      
          // If you have a start page you'd like to load, enter it here
          // Or leave it commented to use what's configured in the config.xml
          // webView.startPage = "";
      
          [self addChildViewController:webView];
      
          [self.view addSubview:webView.view];
      }
      
      #import <UIKit/UIKit.h>
      #import <ifaddrs.h>
      #import <arpa/inet.h>
      #import <Cordova/CDVViewController.h>
      
      @interface RSV : CDVViewController <UIWebViewDelegate>
      {
        IBOutlet CDVViewController *webView;
        IBOutlet UIActivityIndicatorView *activityind;
      }
      - (IBAction)Refresh:(id)sender;
      @end
      
      - (void)viewDidLoad
      {
        webView = [CDVViewController new]; 
        webView.startPage = @"Website";
        [self.webView addSubview:webView.view];
        webView.view.frame = CGRectMake(0, 0, 0, 0);
         [activityind startAnimating];
          [self.webView addSubview: activityind];
          [self Malelka];
      }
      
      -(void) Malelka
      {
          if ([webView.spaghetti isEqualToString:@"TRUE"]){
             [activityind removeFromSuperview];
          }else{
             [NSTimer scheduledTimerWithTimeInterval:.5 target:self selector:@selector(Malelka) userInfo:nil repeats:NO];
          }
      }
      
      - (IBAction)Refresh:(id)sender {
          webView = [CDVViewController new];
          webView.startPage = @"Website";   
          [self.webView addSubview:webView.view];
          webView.view.frame = CGRectMake (0,0,self.view.frame.size.width,(self.view.frame.size.height -44));
          [activityind startAnimating];
          [self.webView addSubview: activityind];
          [self Malelka];
      }
      
      - (void)webViewDidStartLoad:(UIWebView *)webView {}
      - (void)webViewDidFinishLoad:(UIWebView *)subview {}
      - (void)loading {}
      - (void)didReceiveMemoryWarning{[super didReceiveMemoryWarning];}
      
      @end