Question

I'm trying to mimic the Camera app transition from the front to back camera.. it uses a UIViewAnimationOptionTransitionFlipFromLeft..

My current method is taking a picture with the front camera, switch to the back camera, take a picture with the back camera, load them into two UIImageViews and perform the transition with the image views.. (hiding the current camera stream in the process)..

Problem is when I make the call to switch from the front camera to back camera the cameraView (an AVCapturePreviewLayer) instantly switches the view before I can hide it (this occurs in flipCameraToFront on the last line.. [_captureSession commitConfiguration])...

Hopefully this makes sense, heres some of the code I omitted some, if you think it would help let me know and I'll post the rest of it.
Any help would be greatly appreciated, Thanks

//class:RecordViewController
//iVars for this class..   
RecordVideoHandler *_recordHandler;
UIImage *_firstImageForFlip;
UIImage *_secondImageForFlip;
UIImageView *_firstImageViewForFlip;
BOOL isUsingFrontInput;
AVCaptureVideoPreviewLayer *_capturePreviewLayer;
UIView *_capturePreviewView;

- (void)doCameraFlip:(UIButton *)sender
{
    [_recordHandler addStillImageOutput];
    //This method calls imageReturned:(UIImage *)inImage;
    [_recordHandler captureAndReturnStillImage];


}   
- (void)imageReturned:(UIImage *)inImage{

    if(_firstImageForFlip == nil){
        [_capturePreviewLayer setFrame:CGRectZero];
        _firstImageForFlip = inImage;
        _firstImageViewForFlip = [[UIImageView alloc] initWithImage:_firstImageForFlip];


        if(isUsingFrontInput)
            [_firstImageViewForFlip setTransform:CGAffineTransformMakeScale(-1.0, 1.0)];


        [_firstImageViewForFlip setFrame:_capturePreviewView.bounds];
        [_capturePreviewView addSubview:_firstImageViewForFlip];


        if(isUsingFrontInput){
            [_recordHandler flipCameraToBack];
        }else{
            [_recordHandler flipCameraToFront];
        }
        [_recordHandler captureAndReturnStillImage];
    }else{
        _secondImageForFlip = inImage;
        [_recordHandler removeStillImageOutput];
        [self finishCameraFlip];
    }
}
- (void)finishCameraFlip{
    UIImageView *secondImageView = [[UIImageView alloc] initWithImage:_secondImageForFlip];
    [secondImageView setFrame:_capturePreviewView.bounds];

    if(!isUsingFrontInput)
        [secondImageView setTransform:CGAffineTransformMakeScale(-1.0, 1.0)];

    [UIView transitionWithView:_capturePreviewView duration:3.3f
options:UIViewAnimationOptionTransitionFlipFromLeft animations:
     ^{
         [_firstImageViewForFlip removeFromSuperview];
         [_capturePreviewLayer setFrame:_capturePreviewView.bounds];
         [_capturePreviewView addSubview:secondImageView];

     } completion:
     ^(BOOL finished){
         [secondImageView removeFromSuperview];
     }];

    isUsingFrontInput = isUsingFrontInput ? NO : YES;

    _firstImageForFlip = nil;
    _secondImageForFlip = nil;
    }

class:RecordVideoHandler

    //iVars for this class..    
    AVCaptureSession *_captureSession;

    - (void)flipCameraToFront
    {
    [_captureSession beginConfiguration];
    for (AVCaptureInput *input in _captureSession.inputs) {
        if (input == _captureRearInput) {
            [_captureSession removeInput:_captureRearInput];
            [_captureSession addInput:_captureFrontInput];
        }
    }
    _currentCaptureDevice = _captureDeviceFrontFacing;
    [_captureSession commitConfiguration];
}
Was it helpful?

Solution

If anyone was wondering, I figured it out. I had to use performSelectors to wait for the next run loop because the camera flipped instantly whereas the view stuff waited for after the run loop or something... not sure on the specifics, heres the code.

- (void)doCameraFlip:(UIButton *)sender
{
    NSLog(@"doCameraFlip");
    [_recordHandler addStillImageOutput];    
    [_recordHandler captureAndReturnStillImage];    
}
- (void)imageReturned:(UIImage *)inImage{
    [_recordHandler removeStillImageOutput];            
    _imageViewForFlip= [[UIImageView alloc] initWithImage:inImage];
    [_imageViewForFlip setFrame:_containerView.bounds];
    [_containerView addSubview:_imageViewForFlip];


    [self performSelector:@selector(cfe) withObject:nil afterDelay:0.0f];
    [self performSelector:@selector(cfe2) withObject:nil afterDelay:0.0f];

}
- (void)cfe{
    if(isUsingFrontInput){
        [_recordHandler flipCameraToBack];
    }else{
        [_recordHandler flipCameraToFront];
    }

}
- (void)cfe2{
    [UIView transitionWithView:_containerView duration:3.0f options:UIViewAnimationOptionTransitionFlipFromRight animations:^{
        [_imageViewForFlip removeFromSuperview]; 
        [_containerView addSubview:_capturePreviewView]; 
    } completion:nil];
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top