On the camera workflow, the photo is captured and on the next screen, let's call it choose-screen, you can choose if you want to use this photo or retake it.
How do I know, when the camera enteres the preview view?
My issue is that I have added a button to access the camera roll, which works fine. The obstacle is, when taking a photo and entering the preview view (2. Camera View), the button hides the "use photo" option. So I cannot select it. I want to hide the button when entering the preview view or just avoid the preview view.
Below my code
CamViewScreen.h
#import <UIKit/UIKit.h>
#import "CameraViewController.h"
#import <AssetsLibrary/AssetsLibrary.h>
@interface CamViewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
@property (nonatomic, strong) UIImage *image;
@property (nonatomic, strong) UIImage *lastTakenImage;
- (IBAction)takePhoto:(id)sender;
- (IBAction)selectPhoto:(id)sender;
@end
CamViewScreen.m
#import "CamViewController.h"
@interface CamViewController ()
@end
@implementation CamViewController
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
int isAction = 0; // Photo, 1: CameraRoll, 2: Cancel
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
if (![UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
UIAlertView *myAlertView = [[UIAlertView alloc] initWithTitle:@"Error"
message:@"Device has no camera"
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles: nil];
[myAlertView show];
}
isAction = 0;
[self cameraRoll];
}
-(void)viewDidAppear:(BOOL)animated {
// isAction = 0 Photo, 1: CameraRoll, 2: Cancel
DLog(@"###### isAction> %d", isAction);
switch (isAction) {
case 1:
[self selectPhoto:nil];
break;
case 2:
[self dismissViewControllerAnimated:NO completion:nil];
break;
default:
[self takePhoto:nil];
break;
}
}
- (IBAction)takePhoto:(id)sender {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = NO;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.cameraOverlayView = [self addCameraRollButton]; // suggestion from omz
// [self addCameraRollButton:picker.view];
[self presentViewController:picker animated:YES completion:NULL];
}
-(void)prepareCameraRoll {
isAction = 1;
[self dismissViewControllerAnimated:NO completion:nil];
}
- (IBAction)selectPhoto:(id)sender {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:picker animated:YES completion:NULL];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
self.image = chosenImage;
isAction = 0;
[picker dismissViewControllerAnimated:YES completion:NULL];
[self performSegueWithIdentifier:@"toCameraView" sender:info];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
isAction = 2; // Cancel
[picker dismissViewControllerAnimated:YES completion:NULL];
}
# pragma mark - for the cameraOverlayView // suggestion from omz
- (UIView *)addCameraRollButton {
float startY = ([[UIScreen mainScreen] bounds].size.height == 568.0) ? 500.0 : 410.0;
UIButton *rollButton = [UIButton buttonWithType:UIButtonTypeCustom];
rollButton.frame = CGRectMake(230.0, startY, 60.0, 60.0);
rollButton.backgroundColor = [UIColor clearColor];
[rollButton setImage:self.lastTakenImage forState:UIControlStateNormal];
rollButton.imageView.contentMode = UIViewContentModeScaleAspectFill;
[rollButton addTarget:self action:@selector(prepareCameraRoll) forControlEvents:UIControlEventTouchUpInside];
return rollButton;
}
# pragma mark - CameraRoll function and presentation
- (void)addCameraRollButton:(UIView *)picker {
float startY = ([[UIScreen mainScreen] bounds].size.height == 568.0) ? 500.0 : 410.0;
UIButton *rollButton = [UIButton buttonWithType:UIButtonTypeCustom];
rollButton.frame = CGRectMake(230.0, startY, 60.0, 60.0);
rollButton.backgroundColor = [UIColor clearColor];
[rollButton setImage:self.lastTakenImage forState:UIControlStateNormal];
rollButton.imageView.contentMode = UIViewContentModeScaleAspectFill;
[rollButton addTarget:self action:@selector(prepareCameraRoll) forControlEvents:UIControlEventTouchUpInside];
[picker addSubview:rollButton];
}
-(void)cameraRoll {
ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc] init];
[assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupSavedPhotos
usingBlock:^(ALAssetsGroup *group, BOOL *stop) {
if (nil != group) {
// be sure to filter the group so you only get photos
[group setAssetsFilter:[ALAssetsFilter allPhotos]];
[group enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stop) {
if (asset) {
ALAssetRepresentation *repr = [asset defaultRepresentation];
// UIImage *img = [UIImage imageWithCGImage:[repr fullResolutionImage]];
UIImage *img = [UIImage imageWithCGImage:[repr fullScreenImage]];
[self setLastTakenImage:img];
*stop = YES;
}
}];
}
*stop = NO;
} failureBlock:^(NSError *error) {
NSLog(@"error: %@", error);
}];
}
#pragma mark - Navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
CameraViewController *cvc = [segue destinationViewController];
cvc.image = self.image;
DLog(@"%@, cvcimage", cvc.image);
}
@end
cameraOverlayView
property ofUIImagePickerController
to add your custom button. – SemitecameraOverlayView
property. – Apophthegm[self performSegueWithIdentifier:@"toCameraView" sender:info]
from thedidFinishPickingMediaWithInfo:
method, which is called when you take the picture. So "toCameraView" is where you need to implement your 'use photo' button. – RebroadcastCameraViewController
is first called, after the photo was taken; strictly spoken when the button "use photo" is pressed, then thedidFinishPickingMediaWithInfo:
is called. The camera and function to take a picture is only available onCamViewController
. The "use photo" button is the default one, which comes with theUIImagePickerController
. I wonder why the overlay is available on two modal view (the camera where you take the picture, and the preview where you use/retake the photo). How do folks have different overlays here... – Apophthegm