2010-01-17 14 views
15

J'ai remarqué que dans OS 3.1, vous pouvez ajouter une vue de superposition sur le sélecteur d'image avecvue de superposition de caméra - juste pour prévisualiser?

cameraOverlayView 

Cependant, je l'ai aussi remarqué que l'ajout d'une vue via cette méthode affiche également la vue de tout le temps le UIImagePicker est affiché, quand je veux seulement l'afficher pendant la phase d'aperçu.

Existe-t-il un moyen de rendre cela possible uniquement pendant l'aperçu? Je ne veux pas qu'il soit là pendant l'animation de l'obturateur ouvert, ou l'écran qui demande si vous voulez utiliser l'image ou reprendre.

+2

Salut mac_55! Je voulais juste vous rappeler doucement d'accepter/commenter ma réponse mise à jour. –

Répondre

17

J'ai trouvé un moyen pour vous d'atteindre le résultat souhaité que ce soit un peu ... pas si standard. :)

L'idée est de réorganiser un peu l'ordre des vues internes dans la structure utilisations. OK, nous créons donc un objet UIImagePickerController, l'initialisons et lui ajoutons une vue de superposition. Puis-je avoir votre attention s'il vous plaît! L'objet UIView (UIImageView dans l'exemple de code) est masqué dès le début. Ne manquez pas ça. Enfin, nous présentons le contrôleur de sélecteur d'image en tant que contrôleur de vue modale. Ce code devrait être quelque part dans votre applicationDidFinishLaunching:, viewWillAppear: ou similaire sur le point de lancer des méthodes similaires.

UIImagePickerController *anImagePickerController = [UIImagePickerController new]; 
anImagePickerController.delegate = self; 
anImagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera; 

UIImageView *anImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Watermark.png"]]; 
anImageView.frame = CGRectMake(0, 1, anImageView.image.size.width, anImageView.image.size.height); 
anImageView.hidden = YES; 
anImagePickerController.cameraOverlayView = anImageView; 

[viewController presentModalViewController:anImagePickerController animated:NO]; 
[anImagePickerController release]; 

[NSTimer scheduledTimerWithTimeInterval:0.1 
           target:self 
           selector:@selector(timerFireMethod:) 
           userInfo:anImageView 
           repeats:YES]; 
[anImageView release]; 

Avant la vue superposition (anImageView) est publié un NSTimer est créé, initialisé avec anImageView (NSTimeruserInfo propriété) et prévue tout de suite. Voici la méthode qu'il appelle:

- (void)timerFireMethod:(NSTimer*)theTimer { 
    UIView *cameraOverlayView = (UIView *)theTimer.userInfo; 
    UIView *previewView = cameraOverlayView.superview.superview; 

    if (previewView != nil) { 
     [cameraOverlayView removeFromSuperview]; 
     [previewView insertSubview:cameraOverlayView atIndex:1]; 

     cameraOverlayView.hidden = NO; 

     [theTimer invalidate]; 
    } 
} 

Toute NSTimer chose est ajoutée au flux afin d'assurer que les travaux de remise en ordre autour se produira exactement quand le UIImagePickerController sera totalement prêt pour cela.

C'est ça. Ca marche, ce n'est pas standard, c'est dur et rapide. Encore une fois, n'hésitez pas à optimiser et à le rendre «plus clair» (oh s'il vous plaît faites, mon but était de vous montrer le chemin).

+0

Je pensais régler la vue à afficher après une minuterie, mais je ne savais pas si la caméra prenait toujours le même temps de chargement - cela ne dépend pas de la quantité de mémoire utilisée à ce moment-là , et sur quel appareil fonctionne-t-il? par exemple. ça va charger plus vite sur un 3GS que sur un 3G. –

+0

Hé mac_55, j'ai optimisé ma solution - maintenant cela fonctionne parfaitement (aussi bien qu'une solution de travail peut fonctionner). :) HTH –

+0

Désolé pour le retard. Je n'ai pas encore essayé de le tester, mais je suis heureux de le marquer comme la réponse. :) –

-2

Lorsque vous créez le sélecteur, ajoutez l'incrustation au sélecteur (picker.cameraOverlayView = myView).

La superposition ne sera pas dans la photo prise. C'est juste, comme il le dit, une vue en superposition.

Vous pouvez supprimer l'affichage de superposition avant de prendre une photo (méthode takePicture) et ajouter la vue à nouveau dans imagePickerController:didFinishPickingMediaWithInfo:

+0

Désolé, ce n'est pas ce que je cherche. Je veux afficher la superposition seulement avant de prendre la photo. Pas pendant que l'obturateur de la caméra est en train d'animer, ou pendant qu'il vous demande si vous aimez la photo que vous avez prise –

+0

Si vous supprimez l'incrustation (picker.cameraOverlayView = nil) avant d'appeler takePicture, l'incrustation ne sera pas présente lorsque l'obturateur est en animation. – diederikh

+0

Mais comment puis-je le montrer sur l'écran d'aperçu? Ai-je raison de supposer que takePhoto capture tout ce qui est dans l'écran d'aperçu? Mais je veux afficher la superposition sur l'écran de prévisualisation (avant la photo est prise) * confus * –

6

En fait, je voulais faire la même chose et je suis tombé sur une beaucoup plus simple de le faire via ce blog: http://www.alexcurylo.com/blog/2009/06/18/uiimagepickercontroller-in-3-0/

Depuis le UIImagePickerController peut appeler un UINavigatorControllerDelegate, la méthode est en dessous appelée avant l'image le sélecteur est affiché.

Voici le code important:

- (void)navigationController:(UINavigationController *)navigationController 
willShowViewController:(UIViewController *)viewController 
animated:(BOOL)animated 
{ 
    if (!viewController) 
    return; 

    UIView* controllerViewHolder = viewController.view; 
    UIView* controllerCameraView = [[controllerViewHolder subviews] objectAtIndex:0]; 
    UIView* controllerPreview = [[controllerCameraView subviews] objectAtIndex:0]; 
    [controllerCameraView insertSubview:self.overlayView aboveSubview:controllerPreview]; 
} 

espoir qui aide.

18

Je voulais juste montrer une autre possibilité sans subview fiddling. Il existe des notifications système pour les modifications dans CameraPicker. Ils ne sont pas documentés non plus (comme la structure de la sous-vue). Donc, ils sont également sujets à changement. MAIS vous les obtenez.

Vous pouvez vous inscrire pour les utiliser sans nom:

[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(notificationReceived:) name: nil object: nil]; 

Nous obtenons des notifications intéressantes (selfexplaining) ici:

PLCameraControllerPreviewStartedNotification 
PLCameraViewIrisAnimationWillBeginNotification 
PLCameraViewIrisAnimationDidEndNotification 

Recorder_DidStartPreviewing 
Recorder_SourceStarted 
Recorder_WillCapturePhoto 
Recorder_DidCapturePhoto 
Recorder_PhotoStillImageSampleBufferReady 
Recorder_DidStopPreviewing 

_UIImagePickerControllerUserDidCaptureItem // Photo was taken, preview is shown 
_UIImagePickerControllerUserDidRejectItem // Repeat was pressed, camera is shown again 

Vous pouvez les utiliser pour déclencher votre overlayviews état caché ou quoi que ce soit autre.

+0

Vous pensez que votre application pourrait être refusée pour utilisation? –

+0

Non, ce ne sont que des chaînes. Cela devrait fonctionner. Mais je ne l'ai pas encore testé. – calimarkus

+1

Testé cela, et j'ai réussi à modifier mon aperçu pour être différent de ma vue de la caméra en accrochant à "_UIImagePickerControllerUserDidCaptureItem" notification. J'ai remarqué que ni PLCameraViewIrisAnimationWillBeginNotification ni PLCameraViewIrisAnimationDidEndNotification n'ont été lancés (j'utilise iOS 6), donc j'ai dû contourner en utilisant des notifications autour de ces événements, tels que "Recorder_WillCapturePhoto" et "PLCameraControllerPreviewStartedNotification". – Christian