Video camera view in videoViewController works on iPhone but not iPad - ios

I have a bug in a Universal iOS app that does not display the camera view in the iPad frame. The view is offset to the left. The view sits perfectly in an iPhone, but not on iPad. The original code was written 2 years ago and I am wondering if there has been a change in iOS that is now missing from this section of code.
Here is what I have at the moment;
self.preview = [AVCaptureVideoPreviewLayer layerWithSession:self.session];
AVCaptureConnection *avcc = [self.preview connection];
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
[avcc setVideoOrientation:AVCaptureVideoOrientationLandscapeRight];
else
[avcc setVideoOrientation:AVCaptureVideoOrientationLandscapeRight];
CGRect rect = [[[self view] layer] bounds];
[self.preview setBounds:CGRectMake(0, 0, rect.size.height, rect.size.width)];
[self.preview setPosition:CGPointMake(CGRectGetMidY(rect), CGRectGetMidX(rect))];
self.preview.videoGravity = AVLayerVideoGravityResizeAspectFill;

As per the problem , what I can suggest just add this line in viewDidLayoutSubviews() if your project support Auto Layout .
Code:-
{
CGRect bounds=self.view.layer.bounds;
self.preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
self.preview.bounds=bounds;
self.preview.position=CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
}

Related

UIImagePickerController's cameraViewTransform is ignoring 'scaling' and 'translation' on iOS 10 beta

I have been using below code to scale my UIImagePickerController's live preview to fill the entire screen. This worked perfectly till now. Before few days, I installed iOS 10 beta 7 on an iPhone 5 and it doesn't scale anymore. I can see black patch at the bottom of UIImagePickerController's view. Seems like cameraViewTransform is ignoring the CGAffineTransformMakeScale and CGAffineTransformMakeTranslation calls.
This is how I initiate my camera controller. I have set both "allowsEditing" and "showsCameraControls" to 'NO' in order to provide my own custom overlay view.
objImagePickerController =[[UIImagePickerController alloc] init];
objImagePickerController.delegate = self;
objImagePickerController.sourceType =UIImagePickerControllerSourceTypeCamera;
objImagePickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
objImagePickerController.allowsEditing = NO;
objImagePickerController.showsCameraControls= NO;
This is what I use to scale the camera live preview.
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
float screenHeight= MAX(screenSize.height, screenSize.width);
float screenWidth= MIN(screenSize.height, screenSize.width);
float cameraAspectRatio = 4.0 / 3.0;
float imageWidth = floorf(screenWidth * cameraAspectRatio);
float scale = ceilf((screenHeight / imageWidth) * 10.0) / 10.0;
objImagePickerController.cameraViewTransform= CGAffineTransformMakeScale(scale, scale);
This is how I add the camera view as a subview instead of traditional modal presentation method, to suit my own requirements.
[[[UIApplication sharedApplication] keyWindow]addSubview:objImagePickerController.view];
screenshot from iPhone 5s running on iOS 10 beta 8
screenshot from iPhone 5s running on iOS 8.2
As noticeable from the above screenshots, the cameraViewTransform doesn't respect the CGAffineTransformMakeScale in iOS 10 beta.
Did anybody else face this issue? This is a really weird behavior appearing in iOS 10 beta OS. I am unable to find a workaround for this. Please advise.
NOTE:: objImagePickerController is an instance of UIImagePickerController.
Strangely it only allows us to transform it after the presentation was completed.
Example:
self.presentViewController(
self.imagePicker,
animated: true,
completion: {
let screenSize = UIScreen.mainScreen().bounds.size
let ratio: CGFloat = 4.0 / 3.0
let cameraHeight: CGFloat = screenSize.width * ratio
let scale: CGFloat = screenSize.height / cameraHeight
self.imagePicker.cameraViewTransform = CGAffineTransformMakeTranslation(0, (screenSize.height - cameraHeight) / 2.0)
self.imagePicker.cameraViewTransform = CGAffineTransformScale(self.imagePicker.cameraViewTransform, scale, scale)
}
)
This code will transform the camera view to match the screen size.
Note that this is a workaround. It works, but the user will see it resizing upon presentation.
As answered here, this issue has been fixed in iOS 10.2 and you can use the cameraViewTransform property before presenting the camera again.
I've solved by delaying set cameraViewTransform after camera e AVCaptureSessionDidStartRunningNotification is raised:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(cameraIsReadyNotification:) name:AVCaptureSessionDidStartRunningNotification object:nil];
-
- (void)cameraIsReadyNotification:(NSNotification *)notification
{
dispatch_async(dispatch_get_main_queue(), ^{
float scale = ceilf((screenHeight / imageWidth) * 10.0) / 10.0;
objImagePickerController.cameraViewTransform=CGAffineTransformMakeScale(scale, scale);
});
}
I had the same problem earlier in IOS 9.3 also. Here is the code i used
//transform values for full screen support
#define CAMERA_TRANSFORM_X 1
#define CAMERA_TRANSFORM_Y 1.12412
if (IS_IPAD)
CGAffineTransformScale(objImagePickerController.cameraViewTransform, CAMERA_TRANSFORM_X, CAMERA_TRANSFORM_Y);
else if (IS_IPHONE_5_Land||IS_IPHONE_4_Land||IS_IPHONE_6_Land||IS_IPHONE_6_PLUS_Land)
{
objImagePickerController.cameraViewTransform = CGAffineTransformScale(CGAffineTransformIdentity, 2, 2);
}
Hope this helps
I had the same problem in my augmented reality application and finally solved it by using AVFoundation framework instead of UIImagePickerController. It seems that cameraViewTransform no longer works on iOS 10.
The code below worked for me. Add the function to your UIViewController subclass and call it.
- (BOOL) initCamera {
AVCaptureSession *captureSesion = [[AVCaptureSession alloc] init];
if ([captureSesion canSetSessionPreset:AVCaptureSessionPresetHigh]) {
[captureSesion setSessionPreset:AVCaptureSessionPresetHigh];
} else {
return false;
}
AVCaptureDevice *camera = nil;
NSArray<AVCaptureDevice*>* devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
// Select back camera
for (AVCaptureDevice *device in devices) {
if ([device position]==AVCaptureDevicePositionBack) {
camera = device;
break;
}
}
if (camera == nil) {
// Back camera not found.
return false;
}
AVCaptureStillImageOutput *imageOutput = [[AVCaptureStillImageOutput alloc]init];
[imageOutput setOutputSettings: #{AVVideoCodecKey: AVVideoCodecJPEG}];
AVCaptureDeviceInput *deviceInput = [[AVCaptureDeviceInput alloc]initWithDevice:camera error: nil];
if (![captureSesion canAddInput:deviceInput] || ![captureSesion canAddOutput:imageOutput]) {
return false;
}
[captureSesion addInput:deviceInput];
[captureSesion addOutput:imageOutput];
AVCaptureVideoPreviewLayer *layer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:captureSesion];
// "Aspect Fill" is suitable for fullscreen camera.
layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
layer.frame = self.view.bounds;
layer.connection.videoOrientation = AVCaptureVideoOrientationPortrait;
[self.view.layer addSublayer:layer];
[captureSesion startRunning];
return true;
}
The most important thing is to use AVLayerVideoGravityResizeAspectFill. With this configuration, the camera view fills the container view keeping its original aspect ratio.
Don't forget to import the framework:)
#import <AVFoundation/AVFoundation.h>

Objective - C, what does [UIScreen mainScreen].bounds.size.width actually give and what does initWithSize: actually require?

I am writing a GUI, with a main menu, a second screen and a back button to the main menu. From the initial main menu I use the following lines of code:
midScreenX = [UIScreen mainScreen].bounds.size.width/2;
midScreenY = [UIScreen mainScreen].bounds.size.height/2;
WarScene *battle = [[WarScene alloc] initWithSize: CGSizeMake(midScreenX*2, midScreenY*2)];
SKTransition *reveal = [SKTransition revealWithDirection:SKTransitionDirectionDown duration:1.0];
SKView * skView = (SKView *)self.view;
UIView *viewToRemove = [self.view viewWithTag:101];
[viewToRemove removeFromSuperview];
[skView presentScene:battle transition:reveal];
This works... I think. I open up a new scene, my second scene is the correct size and at least fills the screen. There is a node in that scene which is too big for the screen, and I am working on changing that, but I don't think that that would actually effect the UIScreen's bounds.
The problem arises when I return to the main menu with the following code:
midScreenX = [UIScreen mainScreen].bounds.size.width/2;
midScreenY = [UIScreen mainScreen].bounds.size.height/2;
GameScene *map = [[GameScene alloc] initWithSize: CGSizeMake(midScreenX*2 ,midScreenY*2)];
SKTransition *reveal = [SKTransition revealWithDirection:SKTransitionDirectionDown duration:1.0];
SKView * skView = (SKView *)self.view;
UIView *viewToRemove = [self.view viewWithTag:3];
[viewToRemove removeFromSuperview];
[skView presentScene:map transition:reveal];
As far as I can work out, the values being passed through should be exactly the same as the values initially sent for [UIScreen mainScreen].bounds.size and yet the scene which is initialised is far too big.
Is there anything that I could be doing which might affect [UIScreen mainScreen].bounds.size? Or have I misunderstood what init and .bounds actually do?
In terms of what I have already done to try and solve this problem myself, I have looked at examples of how scenes are normally initialised. I see that often values are used in place of .bounds for example :
initWithSize: CGSizeMake(1024,768)
However, wouldn't that mean that on different devices the scene wouldn't be shown properly/fully?
if you are using iOS 6 or iOS 7,
both [UIScreen mainScreen].bounds.size.width and [UIScreen mainScreen].bounds.size.height is same in all orientation..
but in iOS 8 it give one value in landscape and give another value in portrait mode
NSLog(#"width %f",[[UIScreen mainScreen] bounds].size.width); //portrait ios7 or 6 = 320 , landscape ios7 or 6 = 320
NSLog(#"height %f",[[UIScreen mainScreen] bounds].size.height); //portrait ios7 or 6 = 568 , landscape ios7 or 6 = 568
NSLog(#"width %f",[[UIScreen mainScreen] bounds].size.width); //portrait ios8 = 320 , landscape ios8 = 568
NSLog(#"height %f",[[UIScreen mainScreen] bounds].size.height); //portrait ios8 = 568 , landscape ios8 = 320
so we can check conditions like this,
CGFloat midScreenX,midScreenY;
if (UIDeviceOrientationIsLandscape((UIDeviceOrientation)[[UIApplication sharedApplication] statusBarOrientation]))
{
//landscape mode
midScreenX = ([[UIScreen mainScreen]bounds].size.width>[[UIScreen mainScreen]bounds].size.height?[[UIScreen mainScreen]bounds].size.width:[[UIScreen mainScreen]bounds].size.height)/2;
midScreenY = ([[UIScreen mainScreen]bounds].size.width<[[UIScreen mainScreen]bounds].size.height?[[UIScreen mainScreen]bounds].size.width:[[UIScreen mainScreen]bounds].size.height)/2;
}
else
{
//portrait mode
midScreenX = [[UIScreen mainScreen]bounds].size.width/2;
midScreenY = [[UIScreen mainScreen]bounds].size.height/2;
}
I hope you warScene and gameScene are subclass of SKScene. The method initWithSize returns, A newly initialized scene object. and parameter 'size' is The size of the scene in points.
For more information refer https://developer.apple.com/library/prerelease/ios/documentation/SpriteKit/Reference/SKScene_Ref/index.html#//apple_ref/occ/instm/SKScene/initWithSize:

Newly created UIWindow is sideways when app is opened on landscape

I have an iPad application in which I create a new UIWindow at the beginning of the app and show it while I do some resource synchronization. When the app is launched while the iPad is on portrait orientation, everything's fine. However, when on landscape orientation, the newly created UIWindow's size seems fine but it appears sideways and it's coordinates seem all weird. Here are the screenshots for both portrait and landscape orientations:
The landscape one is obtained by rotating to right once.
The piece of code where I create and show the UIWindow is as follows:
UIWindow *window=[UIApplication sharedApplication].keyWindow;
self.progressWindow = [[UIWindow alloc] initWithFrame:window.frame];
self.progressWindow.backgroundColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.5f];
self.progressWindow.windowLevel = UIWindowLevelAlert;
/* some other code to create the subviews */
[self.progressWindow makeKeyAndVisible];
This problem only occurs on iOS 8.
As far as I understood, newly created UIWindow's do not rotate automatically when the orientation changes. I don't know whether this is new to iOS 8 or if it is a bug, but I was able to overcome the problem with the following piece of code:
UIWindow *window=[UIApplication sharedApplication].keyWindow;
self.progressWindow = [[UIWindow alloc] initWithFrame:window.frame];
self.progressWindow.backgroundColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.5f];
self.progressWindow.windowLevel = UIWindowLevelAlert;
/* some other code to create the subviews */
[self handleOrientationChange];
[self.progressWindow makeKeyAndVisible];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleOrientationChange) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];
Implementation for handleOrientationChange is as follows:
#define DegreesToRadians(degrees) (degrees * M_PI / 180)
- (void)handleOrientationChange
{
if (self.progressWindow)
{
// rotate the UIWindow manually
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
[self.progressWindow setTransform:[self transformForOrientation:orientation]];
// resize the UIWindow according to the new screen size
if ([[UIScreen mainScreen] respondsToSelector:#selector(nativeBounds)])
{
// iOS 8
CGRect screenRect = [UIScreen mainScreen].nativeBounds;
CGRect progressWindowFrame = self.progressWindow.frame;
progressWindowFrame.origin.x = 0;
progressWindowFrame.origin.y = 0;
progressWindowFrame.size.width = screenRect.size.width / [UIScreen mainScreen].nativeScale;
progressWindowFrame.size.height = screenRect.size.height / [UIScreen mainScreen].nativeScale;
self.progressWindow.frame = progressWindowFrame;
}
else
{
// iOs 7 or below
CGRect screenRect = [UIScreen mainScreen].bounds;
CGRect progressWindowFrame = self.progressWindow.frame;
progressWindowFrame.origin.x = 0;
progressWindowFrame.origin.y = 0;
progressWindowFrame.size.width = screenRect.size.width;
progressWindowFrame.size.height = screenRect.size.height;
self.progressWindow.frame = progressWindowFrame;
}
}
}
- (CGAffineTransform)transformForOrientation:(UIInterfaceOrientation)orientation {
switch (orientation) {
case UIInterfaceOrientationLandscapeLeft:
return CGAffineTransformMakeRotation(-DegreesToRadians(90));
case UIInterfaceOrientationLandscapeRight:
return CGAffineTransformMakeRotation(DegreesToRadians(90));
case UIInterfaceOrientationPortraitUpsideDown:
return CGAffineTransformMakeRotation(DegreesToRadians(180));
case UIInterfaceOrientationPortrait:
default:
return CGAffineTransformMakeRotation(DegreesToRadians(0));
}
}
I got the idea from the accepted answer of this question.
The shared application maintains a reference to the window through its
key- Window property:
let w = UIApplication.sharedApplication().keyWindow
That reference, however,
is slightly volatile, because the system can create temporary windows
and interpose them as the application’s key window.
try instead
[[UIApplication sharedApplication].delegate window]

how to fix status bar overlap issue in ios 7

I am developing an application that's working fine in IOS6. But in iOS7, the status bar overlaps with the view.
As an example :
I need the status bar first, and then my icons and Remove last .So Please give me any idea about how to remove the overlap.
but I need this
Please give me any idea about my problem
Xcode has iOS 6/7 Deltas which is specifically made to resolve this issue. You have to moved your views 20 pixels down to look right on iOS 7 and in order to make it iOS 6 compatible, You changed Delta y to -20.
Resize the height of views properly on iOS 6 You had to set Delta height as well as Delta Y.
You can see also this - Fix iOS 7 Status bar overlapping
-(void)viewWillLayoutSubviews{
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7)
{
self.view.clipsToBounds = YES;
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenHeight = 0.0;
if(UIDeviceOrientationIsPortrait([[UIApplication sharedApplication] statusBarOrientation]))
screenHeight = screenRect.size.height;
else
screenHeight = screenRect.size.width;
CGRect screenFrame = CGRectMake(0, 20, self.view.frame.size.width,screenHeight-20);
CGRect viewFr = [self.view convertRect:self.view.frame toView:nil];
if (!CGRectEqualToRect(screenFrame, viewFr))
{
self.view.frame = screenFrame;
self.view.bounds = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height);
}
}
}
Try this code.use this code in your AppDelegate.m in did finishlaunching:
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
[application setStatusBarStyle:UIStatusBarStyleLightContent];
self.window.clipsToBounds =YES;
self.window.frame = CGRectMake(0,20,self.window.frame.size.width,self.window.frame.size.height-20);
}
This is the default behavior for UIViewController on iOS 7. The view will be fullscreen and the status bar will cover the top of the view. If you have navigationBar hidden, then you have to adjust all the UIView elements by shifting 20 points.

UIImagePickerController Camera view size issue

I'm building an app using the UIImagePickerController and a custom Overlay. What is does is comparing two images (before image and after image). I am using a custom overlay with the before image when taking the after photo(please see the image attached).
iPhone 5 - ios7
iPhone 4 - iOS7 (When taking the image)
iPhone 4 - iOS 7 (After taking the photo)
See the size difference between iPhone 4 and iPhone 5 camera view.
Application works fine with iPhone 5 screen size(Both ios 6 and ios7). But iPhone 4/4s screen size, it works fine ONLY with iOS6. The issue is with iphone 4/4s(ios7 ONLY), Camera view takes full screen.
That means, you can notice
iPhone 5 camera view size ~ 320*427 (iOS 6 and iOS 7)
iPhone 4 camera view size ~ 320*427 (iOS 6)
BUT
iPhone 4 camera view size ~ 320*480 (iOS 7).
After the image is taken, it fitted to the actual size of 320*427. Because of this issue, I cannot align before image with camera view on iPhone 4 iOS7 (because its screeches to 320*480).
Does anyone faces this strange issue. I tried almost everything, but NO luck. Any ideas please???
This is my piece code for loading the camera view with custom before photo overlay.
- (void)loadCameraWithImage
{
if (!isLoadedOnce)
{
isLoadedOnce = YES;
UIImagePickerController *cameraView = [[UIImagePickerController alloc] init];
cameraView.sourceType = UIImagePickerControllerSourceTypeCamera;
cameraView.wantsFullScreenLayout = NO;
if ([self respondsToSelector:#selector(setEdgesForExtendedLayout:)]) {
[self setEdgesForExtendedLayout:UIRectEdgeNone];
}
// crop before image
UIImage *imgTmpCropped = [self imageByCropping:imgBefore toRect:CGRectMake(0, 0, imgBefore.size.width/2, imgBefore.size.height)];
UIImage *overleyImage = [[UIImage alloc] initWithCGImage: imgTmpCropped.CGImage
scale: [UIScreen mainScreen].scale
orientation: UIImageOrientationDownMirrored];
UIImageView *crosshairView;
UIImageView *beforeView;
CGFloat screenHieght = [UIScreen mainScreen].bounds.size.height;
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad){
//overleyImage = [UIImage imageNamed:#"overlay_ipad.png"];
crosshairView = [[UIImageView alloc] initWithImage:overleyImage];
crosshairView.frame = CGRectMake(0, 0, 768, 1024);
[crosshairView setUserInteractionEnabled:YES];
crosshairView.backgroundColor = [UIColor clearColor];
beforeView = [[UIImageView alloc] initWithImage:overleyImage];
beforeView.frame = CGRectMake(0, 0, 384, 1024);
beforeView.alpha = 0.5;
beforeView.contentMode = UIViewContentModeScaleAspectFill;
}
else {
//overleyImage = [UIImage imageNamed:#"overleyImageAfter.png"];
crosshairView = [[UIImageView alloc] init];
beforeView = [[UIImageView alloc] initWithImage:overleyImage];
if(screenHieght>500){
crosshairView.frame = CGRectMake(0, 60, 320, 480);
beforeView.frame = CGRectMake(0, 70, 160, 427);
}
else{
if([[[UIDevice currentDevice] systemVersion] floatValue] <7.0){
crosshairView.frame = CGRectMake(0, 0, 320, 480);
beforeView.frame = CGRectMake(0, 0, 160, 427);
}
else{
crosshairView.frame = CGRectMake(0, 0, 320, 480);
beforeView.frame = CGRectMake(0, 0, 160, 480);
}
}
[crosshairView setUserInteractionEnabled:YES];
crosshairView.backgroundColor = [UIColor clearColor];
beforeView.alpha = 0.5;
beforeView.contentMode = UIViewContentModeScaleToFill;
}
//[crosshairView addSubview:beforeView];
//set our custom overlay view
cameraView.cameraOverlayView = beforeView;
cameraView.delegate = (id)self;
cameraView.showsCameraControls = YES;
cameraView.navigationBarHidden = YES;
cameraView.toolbarHidden = YES;
[cameraView setHidesBottomBarWhenPushed:YES];
[self.view.window.rootViewController presentViewController:cameraView animated:YES completion:nil];
isLoadedOnce = NO;
}
}
TL;DR
Camera's preview has the same aspect ratio in every device (4:3), screens don't. Asume the preview will have that specific aspect ratio and that it will be placed in a specific position on the screen. Draw your overlay inside that area.
Longer:
We faced the same issue. (Our use case is taking pictures of credit cards with an overlay with the same size as a card). The main problem is that the camera preview's proportions are always the same (4:3) in every device but different phones have different screen proportions (iPhone 4s vs iPhone 5, for example) so the preview's need to be fitted differently and that makes putting an overlay and cropping that very difficult.
Our solution was (the code is somewhat messy and hacky, sorry):
// Adjust camera preview to be a little bit more centered instead of adjusted to the top
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
float cameraAspectRatio = 4.0 / 3.0;
float imageHeight = screenSize.width * cameraAspectRatio;
float verticalAdjustment;
if (screenSize.height - imageHeight <= 54.0f) {
verticalAdjustment = 0;
} else {
verticalAdjustment = (screenSize.height - imageHeight) / 2.0f;
verticalAdjustment /= 2.0f; // A little bit upper than centered
}
CGAffineTransform transform = self.cameraController.cameraViewTransform;
transform.ty += verticalAdjustment;
self.cameraController.cameraViewTransform = transform;
CGRect previewFrame = CGRectMake(0, verticalAdjustment, screenSize.width, imageHeight);
CardPhotoView *overlayView = [[CardPhotoView alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, screenSize.height) widthPercentageOfCamera:self.widthPercentageOfCamera previewFrame:previewFrame];
self.overlayView = overlayView;
self.overlayView.delegate = self;
self.overlayView.useViewport = YES;
[self.overlayView setCameraReady:NO];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(cameraIsReady:) name:AVCaptureSessionDidStartRunningNotification object:nil];
self.cameraController.showsCameraControls = NO;
self.cameraController.navigationBarHidden = YES;
self.cameraController.toolbarHidden = YES;
self.cameraController.cameraOverlayView = self.overlayView;
[self presentViewController:self.cameraController animated:NO completion:nil];
Explanation:
self.cameraController is a UIImagePickerController. CardPhotoView is a view subclass that draws the overlay, it takes the preview frame to know exactly where the preview will be positioned (some devices will have black bars on top and bottom, some won't). It also takes a width percentage to add a little padding to the cropping window.
Also, we have hidden all default camera controls and we have implemented some buttons that will do the work for us. Those buttons are added in the CardPhotoView class and they are drawn taking into account where the preview frame is.

Resources