10

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

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

第一种方法

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

第二种方法

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

“警告:尝试呈现不在窗口层次结构中的视图!”

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

4

5 回答 5

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
于 2013-01-29T15:07:13.133 回答
3

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

Main VC ---present---> Camera VC

所以,如果你打电话

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

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

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

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

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

于 2013-01-27T22:10:49.113 回答
1

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

GitHub 上一定有开源项目,展示了如何在某个地方制作这些视图。或者,如果您不想从头开始,我碰巧发布了一个与您正在寻找的控件非常相似的控件。

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

于 2013-01-26T03:56:30.317 回答
1

我展示了一个自定义相机视图控制器,我在其上添加了一个“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;
}
于 2013-01-28T11:44:22.883 回答
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

于 2013-01-28T07:07:10.820 回答