在我的应用程序上,我在打开的相机上有一个cameraOverlayView
,带有相机按钮的自定义控件。该应用程序允许用户在关闭相机之前拍摄多张照片,因此快门按钮不会调出dismissViewControllerAnimated
,而是在您拍完照片时有一个关闭按钮。
现在,相机覆盖图上的一个按钮是一个图库按钮,允许用户选择保存的图像而不是拍摄新图像。我尝试了两种不同的方法来完成这项工作,都失败了。
第一种方法
使用当前显示叠加层的相同UIImagePickerController
实例,并将sourceType
切换到库。它确实呈现了画廊,但是当拍摄照片时,我不能在不解雇整个叠加层的情况下解雇厨房。
第二种方法
创建UIImagePickerController
的单独实例,将sourceType
设置为图库并尝试调用presentViewController
,然后失败并显示警告:
“警告:尝试出席 谁的观点不在窗口 层次!“
有没有人能解决这个问题?这甚至可能吗?
答案 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”。
最终得到一个嵌套的视图控制器层次结构:
这样的事情:
- (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;
}