10

私のアプリにはcameraOverlayView、カメラボタンのカスタムコントロールを備えた開いたカメラがあります。このアプリでは、ユーザーがカメラを閉じる前に複数の写真を撮ることができるため、シャッターボタンは呼び出されずdismissViewControllerAnimated、代わりに、写真の撮影が終了したときに閉じるボタンがあります。

現在、カメラオーバーレイのボタンの1つは、ユーザーが新しい画像を撮影する代わりに、保存された画像を選択できるようにするギャラリーボタンです。私はこれを機能させるために2つの異なるアプローチを試しましたが、どちらも失敗しました。

最初のアプローチ

UIImagePickerController現在オーバーレイを表示しているのと同じインスタンスを使用してsourceType、ライブラリに切り替えます。ギャラリーは表示されますが、写真をタップすると、オーバーレイ全体を閉じずにギャレーを閉じることはできません。

2番目のアプローチ

の別のインスタンスを作成しUIImagePickerController、をgalleryに設定して、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

2番目のアプローチは正しいです。コードは表示されませんが、コントローラーの階層は次のようになっていると思います。

メインVC---現在--->カメラVC

だから、あなたが呼び出す場合

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

メインVCから、「隠された」VC(カメラVCでカバーされている)から別のVCを表示しようとしています。

重要なのは、カメラVC(cameraVCと呼びましょう)への参照を取得し、メインVCから同様のことを行うことです。

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

これを行うと、「現在の」アクションは、非表示のメインVCではなく、警告なしでカメラVC(表示)によって実行されます。

于 2013-01-27T22:10:49.113 に答える
1

カスタムカメラビューコントローラーを提示し、そこに「SourceTypeCamera」UIImagePickerControllerを含まれている子ビューコントローラーとして追加します。私のカスタムビューコントローラーには、別のUIImagePickerControllerインスタンスを追加するボタンがあります。これは「SourceTypePhotoLibrary」です。

最終的には、ネストされたViewController階層になります。

  • ルート/メインビューコントローラー—現在:
  • 私のカスタムカメラビューコントローラー–子ビューコントローラーとして追加します。
  • カメラまたはフォトライブラリ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 に答える
1

写真を選択するための独自のカスタムギャラリービューをコーディングし、それをcameraOverlayViewサブビュー階層に追加することができます。

GitHubには、これらのビューを作成する方法を示すオープンソースプロジェクトがどこかにあるはずです。あるいは、最初から始めたくない場合は、探しているものと非常によく似たコントロールをリリースしました。

これは非常に単純な手順です。フレームワークに裏打ちされたデータソースを備えたコレクションビューAssetsLibraryです。

于 2013-01-26T03:56:30.317 に答える