10

No puedo ocultar la animación de apertura del obturador de la cámara del iPhone para mi aplicación. Estoy usando UIImagePickerController para acceder a la cámara iphone y usar mis propios controles de superposición. ¿Hay alguna manera de eliminar la animación del obturador inicial (también conocido como Iris) cuando se inicia la cámara? GraciasOcultar/Mostrar animación de iris/obturador de la cámara del iPhone

[EDIT]

Para aquellos que quieren saber la manera de cambiar la animación de la cámara del iris.

La función siguiente se invoca antes de que comience la animación del iris de la cámara.

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated 
{ 
    // Here is were I make the camera preview fit the entire screen. 
    // This might violate the "don't change the view hierarchy"-rule. 
    // So I am not sure if it is valid for App Store commitment. 
    // However, the NSLogs are used to 
    // figure out which subview is the actual Camera Preview which turns out 
    // to be the PLPreviewView. (uncomment to se the printouts). 
    // Change it's size to fit the entire screen (and scale it accordingly 
    // to avoid distorted image 

    NSLog(@"WillShowViewController called..."); 

    NSLog(@"VC:view:subviews\n %@\n\n", [[viewController view] subviews]); 

    NSLog(@"VC:view:PLCameraView:subviews\n %@\n\n", [[[[viewController view] subviews] objectAtIndex: 0] subviews]); 

    NSLog(@"VC:view:PLCameraView:PLPreviewView:subviews\n %@\n\n", [[[[[[viewController view] subviews] objectAtIndex: 0] subviews] objectAtIndex: 0] subviews]); 
    NSLog(@"VC:view:PLCameraView:PLCropOverLay:subviews\n %@\n\n", [[[[[[viewController view] subviews] objectAtIndex: 0] subviews] objectAtIndex: 1] subviews]); 
    NSLog(@"VC:view:PLCameraView:UIImageView:subviews\n %@\n\n", [[[[[[viewController view] subviews] objectAtIndex: 0] subviews] objectAtIndex: 2] subviews]); 

} 

En la función anterior se puede ir a través de cada capa utilizando la sintaxis normal de NSMuatableArray como objectAtIndex

esperanza que esto podría ayudarle.

Saludos,

Ankur

+1

Me gustaría saber la respuesta a esta pregunta también. He estado buscando y no he visto nada. Háganos saber si usted resuelve esto! –

+0

¿Tienes la solución? – Fourj

+0

Sí, encontré la solución jugando con la jerarquía de vistas del UIImagePickerController. – Ankur

Respuesta

0

He ensuciado con esto un poco, pero el envío de varias combinaciones de los métodos de vista del ciclo de vida para el selector de imágenes. (viewWillAppear, viewDidAppear, etc.) Pero no recuerdo cuáles terminaron funcionando.

5

Usando this answer como punto de partida, por fin he resuelto este problema:

NOTA: Esto obviamente no es compatible con 3.3.1.

  1. Escuchar para el UINavigationControllerDidShowViewControllerNotification en su UIImagePickerController, y el PLCameraViewIrisAnimationDidEndNotification a nivel mundial.

  2. Recorrer la jerarquía de vista (comenzando por la principal UIWindow) buscando el PLCameraView. Guarde el índice de la vista contra el UIWindow principal, ya que lo necesitará más adelante.

  3. Quita PLCameraView de superView. Si lo desea, inserte su propia vista en el índice global 0.

  4. Cuando termine la animación del iris, elimine la vista y vuelva a agregar el PLCameraView en su índice original.

0

Disculpa por responder volviendo tan tarde. Descubrí la solución para ese pozo. Jugué con la jerarquía de vistas de la cámara y agregué mi propia capa en la parte superior de todo. La animación tuvo lugar allí y una vez que se abrió el obturador, se eliminó la capa superior. Si alguien necesita ayuda con el código, por favor avíseme, le proporcionaré los pasos y la sintaxis exactos.

-Ankur

+0

Puedes publicar tu código en tu pregunta, ya que estoy enfrentando el mismo problema y necesito ocultar esa animación del obturador. –

0

Ésta función se llama antes de que las cámaras de iris se inicia la animación.

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated 
{ 
    // Here is were I make the camera preview fit the entire screen. 
    // This might violate the "don't change the view hierarchy"-rule. 
    // So I am not sure if it is valid for App Store commitment. 
    // However, the NSLogs are used to 
    // figure out which subview is the actual Camera Preview which turns out 
    // to be the PLPreviewView. (uncomment to se the printouts). 
    // Change it's size to fit the entire screen (and scale it accordingly 
    // to avoid distorted image 

    NSLog(@"WillShowViewController called..."); 

    NSLog(@"VC:view:subviews\n %@\n\n", [[viewController view] subviews]); 

    NSLog(@"VC:view:PLCameraView:subviews\n %@\n\n", [[[[viewController view] subviews] objectAtIndex: 0] subviews]); 

    NSLog(@"VC:view:PLCameraView:PLPreviewView:subviews\n %@\n\n", [[[[[[viewController view] subviews] objectAtIndex: 0] subviews] objectAtIndex: 0] subviews]); 
    NSLog(@"VC:view:PLCameraView:PLCropOverLay:subviews\n %@\n\n", [[[[[[viewController view] subviews] objectAtIndex: 0] subviews] objectAtIndex: 1] subviews]); 
    NSLog(@"VC:view:PLCameraView:UIImageView:subviews\n %@\n\n", [[[[[[viewController view] subviews] objectAtIndex: 0] subviews] objectAtIndex: 2] subviews]); 

} 

En la función anterior se puede ir a través de cada capa utilizando la sintaxis normal de NSMuatableArray como objectAtIndex

esperanza que esto podría ayudarle.

Saludos,

Ankur respuesta

+0

Gracias Duro por formatear el código. No sabía el atajo para eso. – Ankur

0

de Joshwa oculta completamente toda la vista de la cámara durante la duración de la animación del iris. Para mis propósitos, necesitaba la vista de cámara visible, solo sin la animación del iris. Pude lograr esto con un pequeño ajuste de su método. Como otros han notado, esto puede o no estar permitido en la tienda de aplicaciones ya que estamos jugando con la jerarquía de vista y escuchando notificaciones no documentadas. Se necesitan

3 ivars:

UIImagePickerController *imagePickerController; 
UIView *plCameraIrisAnimationView; // view that animates the opening/closing of the iris 
UIImageView *cameraIrisImageView; // static image of the closed iris 

ocultar la imagen del iris cerrado y quitar la vista de la animación. He intentado simplemente escondido de la vista de animación también, pero la animación era todavía visible:

- (void)receivedNavigationControllerDidShowViewControllerNotification:(NSNotification *)notification { 
    UIView *view = imagePickerController.view; 
    [plCameraIrisAnimationView release]; 
    plCameraIrisAnimationView = nil; 
    cameraIrisImageView = nil; 
    while (view.subviews.count && (view = [view.subviews objectAtIndex:0])) { 
     if ([[[view class] description] isEqualToString:@"PLCameraView"]) { 
      for (UIView *subview in view.subviews) { 
       if ([subview isKindOfClass:[UIImageView class]]) { 
        cameraIrisImageView = (UIImageView *)subview; 
       } 
       else if ([[[subview class] description] isEqualToString:@"PLCropOverlay"]) { 
        for (UIView *subsubview in subview.subviews) { 
         if ([[[subsubview class] description] isEqualToString:@"PLCameraIrisAnimationView"]) { 
          plCameraIrisAnimationView = [subsubview retain]; 
         } 
        } 
       } 
      } 
     } 
    } 
    cameraIrisImageView.hidden = YES; 
    [plCameraIrisAnimationView removeFromSuperview]; 
    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"UINavigationControllerDidShowViewControllerNotification" object:nil]; 
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(receivedPLCameraViewIrisAnimationDidEndNotification:) name:@"PLCameraViewIrisAnimationDidEndNotification" object:nil]; 
} 

Cuando la animación ha terminado, mostrar la imagen del iris y volver a agregar la vista de la animación:

- (void)receivedPLCameraViewIrisAnimationDidEndNotification:(NSNotification *)notification { 
    cameraIrisImageView.hidden = NO; 

    UIView *view = imagePickerController.view; 
    while (view.subviews.count && (view = [view.subviews objectAtIndex:0])) { 
     if ([[[view class] description] isEqualToString:@"PLCameraView"]) { 
      for (UIView *subview in view.subviews) { 
       if ([[[subview class] description] isEqualToString:@"PLCropOverlay"]) { 
        [subview insertSubview:plCameraIrisAnimationView atIndex:1]; 
        [plCameraIrisAnimationView release]; 
        plCameraIrisAnimationView = nil; 
        break; 
       } 
      } 
     } 
    } 

    [[NSNotificationCenter defaultCenter] removeObserver:self name:@"PLCameraViewIrisAnimationDidEndNotification" object:nil]; 
} 
+0

No funciona en iOS 5. –

+0

sí, no funciona en iOS5, intenté reemplazarlo con AVCaptureSessionDidStartRunningNotification y AVCaptureSessionDidStopRunningNotification, pero funciona en iOS5 y no con el mismo comportamiento en iOS 4 – AmineG

1

Came a través de una similar: quería que apareciera el obturador cuando tomo la imagen activada por un botón en una vista auto.cameraOverlay de un UIImagePickerController. Al llegar a esta página, investigamos un poco más y llegamos a esta solución.

Sinopsis:

@interface MyController : UIImagePickerController 
...  
- (id) init { 
... 
    self.cameraOverlayView = _my_overlay_; 
    self.showsCameraControls = NO; 
... 
} 
... 
- (void) onMyShutterButton { 
    [self takePicture]; 
     // You want the shutter animation to happen now. 
     // .. but it does not. 
} 

Solución:

// Some constants for the iris view and selector 
NSString* kIrisViewClassName = @"PLCameraIrisAnimationView"; 
SEL kIrisSelector = NSSelectorFromString(@"animateIrisOpen"); 

@implementation MyController { 
... 
    UIView* iris_; 
} 
- (void) viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    // Find the iris view in the siblings of your overlay view 
    for (UIView* view in self.cameraOverlayView.superview.subviews) { 
     if ([kIrisViewClassName isEqualToString:[[view class] description]]) { 
      // It will be hidden by 'self.showsCameraControls = NO'. 
      view.hidden = false; 
      // Extra precautions - as this is undocumented. 
      if ([view respondsToSelector:kIrisSelector]) { 
       iris_ = view; 
      } 
      break; 
     } 
    } 
} 
- (void) animateIrisOpen { 
    if (iris_) { 
     [iris_ performSelector:kIrisSelector]; 
    } 
} 
... 
- (void) onMyShutterButton { 
    [self takePicture]; 
    [self animateIrisOpen]; // Voila - the shutter happens 
} 
0

Para exponer sobre la respuesta de Catalin, (lo cual era genial por cierto), me pareció que si cambia el método de "animateIrisOpen" ligeramente , la presentación es una fracción mejor ... pero notable.

- (void) animateIrisOpen { 
    if (iris_) { 
     iris_.hidden = NO; 
     [iris_ performSelector:kIrisSelector]; 
    } 
} 
Cuestiones relacionadas