在打开的相机上呈现相机胶卷UIImagePickerController

时间:2013-01-15 02:17:08

标签: ios objective-c uiimagepickercontroller

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

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

第一种方法

使用当前显示叠加层的相同UIImagePickerController实例,并将sourceType切换到库。它确实呈现了画廊,但是当拍摄照片时,我不能在不解雇整个叠加层的情况下解雇厨房。

第二种方法

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

  

“警告:尝试出席    谁的观点不在窗口   层次!“

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

5 个答案:

答案 0 :(得分:14)

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

#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

答案 1 :(得分:3)

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

主要VC ---礼物--->相机VC

所以,如果你打电话

[self presentViewController:picker animated:YES completion:^{}];
从您的主VC中

,您试图从“隐藏”VC中显示另一个VC(由相机VC覆盖)。

关键是要参考你的相机VC(让我们称之为cameraVC),并从Main VC做类似的事情:

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

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

答案 2 :(得分:1)

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

GitHub上必须有开源项目,它们展示了如何在某个地方创建这些视图。或者,如果你不想从头开始,我碰巧有released a control very similar你正在寻找的东西。

这是一个非常简单的过程 - 一个带有AssetsLibrary框架支持的数据源的集合视图。

答案 3 :(得分:1)

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

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

答案 4 :(得分:1)

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

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

  • root /主视图控制器 - 呈现:
  • 我的自定义相机视图控制器 - 添加为子视图控制器:
  • 相机相片库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;
}