Make a UIView display the camera view using UIImagePickerController - ios

I'm trying to display the image a the camera sees into my own custom view. I DO NOT want to use Apple's own overlay property for UIImagePickerController: cameraOverlayView.
I don't want an overlay, but for it to just display in my particular view. The only way I've been able to do it was creating a subview in my UIView, but doing this doesn't allow me to use any of my own custom buttons I've made over my UIView . My code so far is:
UIImagePickerController *imagePickerController = [[UIImagePickerController alloc] init];
[imagePickerController setSourceType:UIImagePickerControllerSourceTypeCamera];
[imagePickerController setShowsCameraControls:NO];
[imagePickerController setEditing:NO];
[imagePickerController setNavigationBarHidden:YES];
[self.videoPreviewView addSubview:[imagePickerController view]];
[imagePickerController viewWillAppear:YES];
where videoPreviewView is the outlet for my UIView!
Any suggestions? Thanks!

I have not tried it your way myself, but I also wanted to create a custom camera view. This might not be what you are looking for, but it is an alternative. I created a custom UIView together with .xib file.
In the .m file you just call the appropriate delegate methods to the ViewController where you instantiated the imagePicker. In this ViewController you then call appropriate methods like takePicture.
This way you can make the overlay look any way you like with the xib file. You can instantiate the image picker
FALKCameraView.h :
#protocol CameraViewDelegate <NSObject>
- (void)cameraPressed;
- (void)buttonPressed;
//etc
#end
#interface FALKCameraView : UIView
#property (nonatomic, assign) NSObject<CameraViewDelegate> *delegate;
//Camera Button pressed- notifies CameraViewDelegate
- (IBAction)cameraPressed:(id)sender;
//Button pressed - notifies CameraViewDelegate
-(IBAction)buttonPressed:(id)sender;
#end
FALKCameraView.m:
#implementation FALKCameraView
#synthesize delegate;
- (IBAction)cameraPressed:(id)sender{
[delegate cameraPressed];
}
-(IBAction)buttonnPressed:(id)sender{
[delegate buttonPressed];
}
#end
FALKCameraViewController.h:
#interface FALKCameraViewController : UIViewController <UIImagePickerControllerDelegate, CameraViewDelegate>
- (void)cameraPressed;
- (void)buttonPressed;
#end
FALKCameraViewController.m:
#interface FALKCameraViewController
#property (strong,nonatomic) UIImagePickerController *imagePicker;
#end
#implementation FALKCameraViewController
#synthesise imagePicker;
-(void)setUpCamera{
if ([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeCamera]){
imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType =
UIImagePickerControllerSourceTypeCamera;
imagePicker.showsCameraControls = NO;
imagePicker.allowsEditing = NO;
imagePicker.mediaTypes = #[(NSString *) kUTTypeImage];
NSString *nibName = #"FALKCameraView";
NSArray *nibs = [[NSBundle mainBundle] loadNibNamed:nibName
owner:nil
options:nil];
if([nibs count]){
id nib = [nibs objectAtIndex:0];
if([nib isKindOfClass:[FALKCameraView class]]){
FALKCameraView *view = (FALKCameraView*)nib;
view.delegate = self;
imagePicker.cameraOverlayView = view;
}
}
[self presentViewController:imagePicker
animated:NO completion:nil];
}
}
-(void)cameraPressed:(id)sender{
[imagePicker takePicture];
}
#end

Hope it will work and i just added a single view you can add any custom object to overlayview of the picker
if ([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeCamera]){
imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType =
UIImagePickerControllerSourceTypeCamera;
imagePicker.showsCameraControls = NO;
imagePicker.allowsEditing = NO;
NSString *nibName = #"CameraView";
NSArray *nibs = [[NSBundle mainBundle] loadNibNamed:nibName
owner:nil
options:nil];
if([nibs count]){
id nib = [nibs objectAtIndex:0];
if([nib isKindOfClass:[CameraView class]]){
CameraView *view = (CameraView*)nib;
view.delegate = self;
imagePicker.cameraOverlayView = view;
}
}
[self presentViewController:imagePicker
animated:NO completion:nil];
}

Related

UIImagePickerController crashed with "[UIViewController _setCameraOverlayView:]: unrecognized selector" on iOS 11

I'm trying to create a customized UIImagePickerController with the following code.
ECPhotoPickerController.h
#interface ECPhotoPickerController : UIImagePickerController
#property (strong, nonatomic) void(^didFinishSavingPhoto)(NSURL* url, UIImage* image);
#property (strong, nonatomic) void(^didDismissed)(void);
#end
ECPhotoPickerController.m
...
- (void)viewDidLoad {
[super viewDidLoad];
self.sourceType = UIImagePickerControllerSourceTypeCamera;
self.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
self.showsCameraControls = false;
[self setCameraOverlayView:self.overlayView];
self.delegate = self;
}
...
The customized image picker controller will be presented after I tapped a button, which would invoke the following method.
- (void)showImagePicker {
ECPhotoPickerController* vc = [[ECPhotoPickerController alloc] init];
vc.didFinishSavingPhoto = ^(NSURL *url, UIImage *image) {
self.selectedImage = image;
};
vc.didDismissed = ^{
// dismissed
};
[self presentViewController:vc animated:true completion:nil];
}
But the app will only crash on iOS 11 with the log
[UIViewController _setCameraOverlayView:]: unrecognized selector sent to instance 0x108403dd0
and there is anther weird log before the crash.
[] <<<< AVOutputDeviceDiscoverySession (FigRouteDiscoverer) >>>> -[AVFigRouteDiscovererOutputDeviceDiscoverySessionImpl outputDeviceDiscoverySessionDidChangeDiscoveryMode:]: Setting device discovery mode to DiscoveryMode_None (client: ECalligraphy)
The customized image picker class obviously inherit from UIImagePickerController.
And when I initialized it with [[ECPhotoPickerController alloc] init], it should invoke the super class's initialization since I didn't implement the initialization of ECPhotoPickerController.
I'm really confused about this crash.
Any advice will be appreciated.
I final found the reason!
The sourceType should be specified before the view controller start to be
load on iOS 11.
That means, you should set the value of sourceType during the initialization of your customized view controller or do it for the instance before load.
- (instancetype)init { // `initFromNibName` etc. depends on the way you initialize it.
if (self = [super init]) {
self.sourceType = UIImagePickerControllerSourceTypeCamera;
self.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto;
self.showsCameraControls = false;
self.delegate = self;
}
return self;
}
- (void)viewDidLoad {
[super viewDidLoad];
}
Or
- (void)showImagePicker {
ECPhotoPickerController* vc = [[ECPhotoPickerController alloc] init];
vc.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:vc animated:true completion:nil];
}

dealloc UIImagePickerController error

I have a view which contains a button image picker. When I close the view I am also deallocating the UIImagePickerController.
#interface XXPictureCell()<UIImagePickerControllerDelegate>
#property (nonatomic, strong) UIImagePickerController *imagePickerController;
#end
#implementation XXPictureCell
- (void)dealloc
{
self.imagePickerController.delegate = nil;
}
//...
- (UIImagePickerController *)imagePickerController
{
if (!_imagePickerController)
{
_imagePickerController = [[UIImagePickerController alloc] init];
_imagePickerController.delegate = self;
_imagePickerController.allowsEditing = YES;
_imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
_imagePickerController.cameraDevice = UIImagePickerControllerCameraDeviceFront;
}
return _imagePickerController;
}
#end
The error I keep receiving is
Cannot form weak reference to instance (0x7fa9e18dc600) of class XXPictureCell. It is possible that this object was over-released, or is in the process of deallocation.

set cameraOverlayView with xib

I created a simple xib file with a UIView and a UILabel in the middle of the view. I then set the owner of the xib to be the ViewController that will be using it. I created an outlet from the UIView to my ViewController and did the following:
imagePicker.cameraOverlayView = self.cameraOverlay;
The problem I am having is that it is not appearing when I open the camera. If I create the UIView programmatically it works, but it doesn't seem to work if I use a xib file.
Below is the code where I set the overlay, and camera:
- (IBAction)takeVideo:(id)sender {
UIImagePickerController *imagePicker =
[[UIImagePickerController alloc] init];
NSArray *availableTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];
if ([availableTypes containsObject:(__bridge NSString *)kUTTypeMovie]) {
[imagePicker setMediaTypes:#[(__bridge NSString *)kUTTypeMovie]];
}
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePicker.delegate = self;
imagePicker.cameraOverlayView = self.cameraOverlay;
[self presentViewController:imagePicker animated:YES completion:nil];
}
The camerOverlay is (strong, nonatomic)
Have you loaded the nib in code?
self.cameraOverlay = [[[NSBundle mainBundle] loadNibNamed:#"YourNibNameHere" owner:self options:nil] objectAtIndex:0];
Place this in your viewDidLoad method.

iOS how to start the image picker

I have a UIButton and when the user clicks it, I want to start the image picker controller
I already configure what I think it is enough but I couldn't know what is the message that I have to pass to that image picker to start working
This is my code
#import "ImagePickerViewController.h"
#interface ImagePickerViewController ()
#property (weak, nonatomic) IBOutlet UIImageView *image;
#end
#implementation ImagePickerViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}
- (IBAction)SelectImage:(id)sender {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc]init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
#end
I have already set the correct protocols:
#interface ImagePickerViewController : UIViewController < UINavigationControllerDelegate,UIImagePickerControllerDelegate>
#end
You need to present the UIImagePicker
- (IBAction)SelectImage:(id)sender
{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc]init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentViewController:imagePicker animated:NO completion:nil];
}
You can show the picker with:
[self presentViewController:imagePicker animated:YES completion:NULL];
And then in your delegate callback imagePickerController:didFinishPickingMediaWithInfo you get the image and dismiss the picker again:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
UIImage *image = info[UIImagePickerControllerEditedImage];
[picker dismissViewControllerAnimated:YES completion:NULL];
}
You have to tell your view controller class to show the UIImagePickerController.
Simply use
[self presentViewController:imagePicker animated:YES completion:nil];
This will present it modally. If you are running on an iPad, you instead have to present it in a popover controller, as follows:
Declare a new property in the #interface:
#property (nonatomic, strong) UIPopoverController* imagePickerPopover;
Present the popover controller e.g:
UIButton* button = sender;
self.imagePickerPopover = [[UIPopoverController alloc] initWithContentViewController:self.imagePicker];
[self.imagePickerPopover presentPopoverFromRect:button.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionRight animated:YES];

UIPopoverController for iPad "must not be called with `nil`" error

I am trying to make an iPhone app work in an iPad but the UIPopoverController is
comming back with error.
- (IBAction)photoTapped1 {
if(UI_USER_INTERFACE_IDIOM()== UIUserInterfaceIdiomPhone){
// If in editing state, then display an image picker; if not, create and push a photo view controller.
if (self.editing) {
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
[self presentViewController:imagePicker animated:YES completion:nil];
[imagePicker release];
} else {
RecipePhotoViewController *recipePhotoViewController = [[RecipePhotoViewController alloc] init];
recipePhotoViewController.hidesBottomBarWhenPushed = YES;
recipePhotoViewController.recipe = recipe;
[self.navigationController pushViewController:recipePhotoViewController animated:YES];
[recipePhotoViewController release];
}
}else{
if (self.editing){
self.popover = [[UIPopoverController alloc] initWithContentViewController:popover];
self.popover.delegate =self;
[popover release];
}else{
RecipePhotoViewController *recipePhotoViewController = [[RecipePhotoViewController alloc] init];
recipePhotoViewController.hidesBottomBarWhenPushed = YES;
recipePhotoViewController.recipe = recipe;
[self.navigationController pushViewController:recipePhotoViewController animated:YES];
[recipePhotoViewController release];
}}}
The error I am getting is:
'NSInvalidArgumentException', reason: '-[UIPopoverController initWithContentViewController:] must not be called with nil.'
Anyone available to give me a hand on this code, I have looked on the internet for solutions and samples but can not seem to make it work.
Thank you.
___ added to original question_____
I am adding the recipePhotoViewController here, I am assuming that ImageView manipulation is the same for iPhone and iPad.
my.h File
#class Recipe;
#interface RecipePhotoViewController : UIViewController {
#private
Recipe *recipe;
UIImageView *imageView;
}
#property(nonatomic, retain) Recipe *recipe;
#property(nonatomic, retain) UIImageView *imageView;
#end
Here is my .m file
#implementation RecipePhotoViewController
#synthesize recipe;
#synthesize imageView;
- (void)loadView {
self.title = #"Photo";
imageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].applicationFrame];
imageView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
imageView.contentMode = UIViewContentModeScaleAspectFit;
imageView.backgroundColor = [UIColor blackColor];
self.view = imageView; }
- (void)viewWillAppear:(BOOL)animated {
imageView.image = [recipe.image valueForKey:#"image"];}
- (BOOL)shouldAutorotateToInterfaceOrientation: (UIInterfaceOrientation)interfaceOrientation {
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
- (void)dealloc {
[imageView release];
[recipe release];
[super dealloc];
} #end
You are initializing the popover controller in a wrong way:
self.popover = [[UIPopoverController alloc] initWithContentViewController:popover];
You should pass the controller you would like to display inside of the popover -- not the popover itself (which is nil since you have not yet initialised it)!
Maybe this would do it for you?
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
self.popover = [[UIPopoverController alloc] initWithContentViewController:imagePicker];
If this is correct, then you should also present the pop over you have just created: – presentPopoverFromRect:inView:permittedArrowDirections:animated:
-- e.g.:
[self.popover presentPopoverFromRect:sender.frame inView:[self view] permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
where sender is the argument to :
- (IBAction)photoTapped1:(id)sender {
The content of your popover which you store in the variable popover is obviously nil. I can't see it ever being created in the code you provided.
Maybe you intended to present the Recipe photo controller as the content of the popover. In that case you would do something like
RecipePhotoViewController *recipePhotoViewController = [[RecipePhotoViewController alloc] init];
self.popover = [[UIPopoverController alloc] initWithContentViewController:recipePhotoViewController];
problem is in this line of your code ,
self.popover = [[UIPopoverController alloc] initWithContentViewController:popover];
try like this
UIViewController* popoverContent = [[UIViewController alloc] init];
UIView* popoverView = [[UIView alloc] initWithFrame:CGRectMake(0, 400, 320, 260)];
popoverContent.view = popoverView;
//Add what ever you want popoverView
self.popover = [[UIPopoverController alloc] initWithContentViewController:popoverContent];
self.popover.delegate =self;

Resources