RobertJoseph
RobertJoseph

Reputation: 8158

Simulate a "picture taken" screen flash

I have an AV Foundation app that simulates taking a picture (like the camera app). Normally the following works for me, but isn't in this instance.

This code executes within an action in my view controller. It contains a single full-screen UIView (videoPreviewLayer) which has a AVCaptureVideoPreviewLayer attached. The animation executes but nothing is displayed. Note also that I am using ARC, iOS 6, iPhone 4S, iPad3.

// Flash the screen white and fade it out
UIView *flashView = [[UIView alloc] initWithFrame:[[self videoPreviewView] frame]]; 
[flashView setBackgroundColor:[UIColor whiteColor]];
[[[self view] window] addSubview:flashView];

[UIView animateWithDuration:1.f
             animations:^{
                 [flashView setAlpha:0.f];
             }
             completion:^(BOOL finished){
                 [flashView removeFromSuperview];
             }
 ];

Here is how I attach the AVCaptureVideoPreviewLayer:

 // Setup our preview layer so that we can display video from the camera
captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];

CALayer *viewLayer = videoPreviewView.layer;
viewLayer.masksToBounds = YES;

captureVideoPreviewLayer.frame = videoPreviewView.bounds;

[viewLayer insertSublayer:captureVideoPreviewLayer below:[[viewLayer sublayers] objectAtIndex:0]];

NOTE After further investigation, the flash is occurring although intermittently. Generally it seems to become visible about 5-10 seconds after it should start. I've also seen it happen run twice in quick succession even though I call the code once.

Upvotes: 11

Views: 3370

Answers (2)

neoneye
neoneye

Reputation: 52221

your code as swift3

let shutterView = UIView(frame: cameraView.frame)
shutterView.backgroundColor = UIColor.black
view.addSubview(shutterView)
UIView.animate(withDuration: 0.3, animations: {
    shutterView.alpha = 0
}, completion: { (_) in
    shutterView.removeFromSuperview()
})

Upvotes: 7

RobertJoseph
RobertJoseph

Reputation: 8158

My problem was that the "flash" code was being called from an AV Foundation callback. The callback was not running on the main thread thus any UI code wouldn't execute correctly. That solution was to do something like this:

dispatch_async(dispatch_get_main_queue(), ^{ /* execute flash code */ });

Upvotes: 5

Related Questions