【问题标题】:Presenting camera roll UIImagePickerController over open camera在打开的相机上展示相机胶卷 UIImagePickerController
【发布时间】:2013-01-15 02:17:07
【问题描述】:

在我的应用程序中,我在打开的相机上有一个cameraOverlayView,带有相机按钮的自定义控件。该应用程序允许用户在关闭相机之前拍摄多张照片,因此快门按钮不会调用dismissViewControllerAnimated,而是在您完成拍照时有一个关闭按钮。

现在,相机叠加层上的按钮之一是图库按钮,允许用户选择保存的图像而不是拍摄新图像。我尝试了两种不同的方法来完成这项工作,但都失败了。

第一种方法

使用当前呈现覆盖的相同UIImagePickerController 实例并将sourceType 切换到库。它确实会显示画廊,但是当点击照片时,我无法在不关闭整个叠加层的情况下关闭厨房。

第二种方法

创建UIImagePickerController 的单独实例,将sourceType 设置为图库并尝试调用presentViewController,然后失败并显示警告:

“警告:尝试在 谁的视野不在窗内 等级制度!”

有没有人可以解决这个问题?这甚至可能吗?

【问题讨论】:

  • 是的,这是可能的。您能否向我们展示您的第二种方法的代码?我想你可能在错误的地方调用它。看看这个:stackoverflow.com/a/12320222/361247
  • 我尝试了第二种方法。它很好。我想你可以检查你的来源。也许这是 Enrico Susatyo 评论的问题。祝你好运~~

标签: ios objective-c uiimagepickercontroller


【解决方案1】:

试试这个~~我认为这是你的目标。

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, strong) UIImagePickerController *imagePicker;

@end

@implementation ViewController

@synthesize imagePicker = _imagePicker;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

}


- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:YES];

    sleep(2);

    _imagePicker = [[UIImagePickerController alloc] init];
    [_imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
    [_imagePicker setDelegate:self];

    UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 50, 100, 30)];
    [button setTitle:@"Library" forState:UIControlStateNormal];
    [button setBackgroundColor:[UIColor darkGrayColor]];
    [button addTarget:self action:@selector(gotoLibrary:) forControlEvents:UIControlEventTouchUpInside];

    [_imagePicker.view addSubview:button];

    [self presentViewController:_imagePicker animated:YES completion:nil];
}
- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(IBAction)gotoLibrary:(id)sender
{
    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
    [imagePicker.view setFrame:CGRectMake(0, 80, 320, 350)];
    [imagePicker setSourceType:UIImagePickerControllerSourceTypeSavedPhotosAlbum];
    [imagePicker setDelegate:self];

    [_imagePicker presentViewController:imagePicker animated:YES completion:nil];
}


- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    [picker dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
    [picker dismissViewControllerAnimated:YES completion:nil];
}
@end

【讨论】:

  • 你测试过这个吗?看来这是我在第二种方法中正在做的事情,它正在抛出错误。
  • 当然可以。点击相机视图中的按钮,它显示照片库视图。我刚刚创建了一个新项目,编辑了.m文件,并将情节提要中的视图连接到控制器的视图。那就是我所做的一切。
  • 为什么在 viewDidAppear.我把我的拿出来,它仍然有效。我们还在等什么?如果真的需要延迟?是否有更确定的方式来实现这一点?
  • 这条线是做什么用的? [imagePicker.view setFrame:CGRectMake(0, 80, 320, 350)];
  • 请不要调用 sleep(2);在主线程上 >
【解决方案2】:

第二种方法是正确的。 我没有看到您的代码,但我认为您的控制器层次结构类似于:

主 VC ---present---> 相机 VC

所以,如果你打电话

[self presentViewController:picker animated:YES completion:^{}];

在您的主 VC 中,您正试图从“隐藏”的 VC(被相机 VC 覆盖)中显示另一个 VC。

关键是引用您的相机 VC(我们称之为 cameraVC)并在 Main VC 中执行类似的操作:

 [cameraVC presentViewController:theOtherPicker animated:YES completion:^{}];

这样做,“当前”动作由相机 VC(可见)完成,没有警告,而不是由隐藏的主 VC。

【讨论】:

    【解决方案3】:

    您可以编写自己的自定义图库视图来选择照片,然后将其添加到 cameraOverlayView 子视图层次结构中。

    GitHub 上一定有开源项目,展示了如何在某个地方制作这些视图。或者,如果您不想从头开始,我恰好有 released a control very similar 来满足您的需求。

    这确实是一个非常简单的过程 - 一个集合视图,其数据源由 AssetsLibrary 框架支持。

    【讨论】:

    • 您的控件是否显示为模态?
    • 是的,你将它包装在一个导航控制器中,然后以模态方式呈现。
    【解决方案4】:

    我将按如下方式设置捕获会话:

    - (void)setupCaptureSession
    {
        NSError* error = nil;
    
        // Create the session
        _captureSession = [[AVCaptureSession alloc] init];    
        _captureSession.sessionPreset = AVCaptureSessionPresetMedium;
        AVCaptureDevice* device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    
        AVCaptureDeviceInput* input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
    
        [_captureSession addInput:input];
        AVCaptureVideoDataOutput* output = [[AVCaptureVideoDataOutput alloc] init];
        [_captureSession addOutput:output];
    
        // Configure your output.
       dispatch_queue_t queue = dispatch_queue_create("myCameraOutputQueue", NULL);
       //If you want to sebsequently use the data, then implement the delegate.
       [output setSampleBufferDelegate:self queue:queue]; 
    }
    

    完成后,您可以按如下方式创建预览层:

    _previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_captureSession];
    [_captureSession startRunning];
    

    然后将预览层添加到您的视图中:

    _myView.layer addSubLayer:_previewLayer];
    

    现在您已经设置好了,我将添加一个自定义图像选择器,例如:https://github.com/arturgrigor/AGImagePickerController

    【讨论】:

    • 这个自定义 ImagePicker 将自己显示为模态,我已经有一个打开的相机模态,我认为这不会起作用。
    • 它不一定是模态的,我相信你可以使用所有源代码解决这个问题。 .顺便说一句:它是 gitbub 上的众多项目之一。我选择了那个,因为它包含图片。 . . .话虽如此,乍一看,这里似乎还有其他几个很好的答案。 . .
    • 如果我尝试在相机 ImagePicker 上显示图库 ImagePicker:code[self presentViewController:galleryImagePicker animated:YES completion:nil];
    【解决方案5】:

    我展示了一个自定义相机视图控制器,我在其上添加了一个“SourceTypeCamera”UIImagePickerController 作为包含的子视图控制器。我的自定义视图控制器有一个按钮,该按钮又添加了另一个 UIImagePickerController 实例,这是一个“SourceTypePhotoLibrary”。

    你最终得到一个嵌套的视图控制器层次结构:

    • 根/主视图控制器——呈现:
    • 我的自定义相机视图控制器– 添加为子视图控制器:
    • 任一相机照片库UIImagePickerController

    类似这样的:

    - (void)viewDidLoad { (id<UIImagePickerControllerDelegate,UINavigationControllerDelegate>)theDelegate {
        [super viewDidLoad];
        [self startImagePickerWithSourceType:UIImagePickerControllerSourceTypeCamera
                                    delegate:self];
        // configure button in camera overlay to call -pickPhotoTapped
    }
    
    - (void) pickPhotoTapped {
        [self startImagePickerWithSourceType:UIImagePickerControllerSourceTypePhotoLibrary
                                    delegate:self];
    }
    
    - (BOOL) startImagePickerWithSourceType:(UIImagePickerControllerSourceType)sourceType
                                   delegate:(id<UIImagePickerControllerDelegate,UINavigationControllerDelegate>)theDelegate {
        if (([UIImagePickerController isSourceTypeAvailable:sourceType] == NO)
                || (theDelegate == nil))
            return NO;
    
        self.cameraUI = [[UIImagePickerController alloc] init];
        self.cameraUI.sourceType = sourceType;
        self.cameraUI.view.frame = self.view.bounds;
        self.cameraUI.delegate = theDelegate;
    
        if (sourceType == UIImagePickerControllerSourceTypeCamera) {
            self.cameraUI.allowsEditing = NO;
            self.cameraUI.showsCameraControls = NO;
            self.cameraUI.cameraOverlayView = [self overlayView];
        }
    
        [self addChildViewController:self.cameraUI];
        [self.view addSubview:self.cameraUI.view];
        [self.cameraUI didMoveToParentViewController:self];
    
        return YES;
    }
    

    【讨论】:

    • 我的问题是我想在相机上展示画廊,所以必须同时展示 UIImagePickerControllers,而不是任何一个。
    • 尝试使用这种方法,但实例化第二个 UIImagePickerController 实例并将其作为子视图控制器添加到现有 UIImagePickerController 实例中。如果你想要从底部向上滑动的过渡,动画帧更改或使用 +[UIView transitionFromView:toView:duration:options:completion:]
    • @Rafael 你的设备是什么??当我通过弹出库视图尝试第二种方法时,我在 iPad 中显示了这两个视图。
    • @StevenJian 这是一个仅限 iPhone 的应用程序。
    • @Yang 这行得通吗?不幸的是,我现在无法测试。我应该使用 [UIView addSubView] 添加第二个 UIImagePickerController 吗?似乎此方法不起作用,因为它在 Class Reference 中声明:“转换的起始视图。默认情况下,此视图作为转换的一部分从其父视图中删除。”
    猜你喜欢
    • 1970-01-01
    • 2011-11-08
    • 1970-01-01
    • 1970-01-01
    • 2014-09-05
    • 1970-01-01
    • 2013-08-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多