Hi I am very new to developing iOS application please help me. i am facing a problem regarding capturing image by using UIImagePicker. I have integrated hip mob app in to our application.
In that window i want to show a UIButton so that the user click on that UIButton should capture the image. when i click on the button its throwing an message as (whose view is not in the window hierarchy!).
I think this happens due to this chat window. here is my code snippet.!
[[HMService sharedService] openChat:self withSetup:^(HMChatViewController * controller)
{
controller.chatDelegate = self;
controller.chatView.receivedMessageFont = [UIFont systemFontOfSize:20.0];
controller.navigationBarHidden = YES;
UIView * viewObjForVehicleDetails = [[UIView alloc]init];
UIButton * btnForCaputrePhoto = [[UIButton alloc]init];
[btnForCaputrePhoto addTarget:self action:#selector(CapturePhotoImage) forControlEvents:UIControlEventTouchUpInside];
btnForCaputrePhoto.frame = CGRectMake(55, 90, 103, 85);
[controller.chatView addSubview:viewObjForVehicleDetails];
[viewObjForVehicleDetails addSubview:btnForCaputrePhoto];
[[controller.chatView table] registerClass:[ChatTableViewCell class] forCellReuseIdentifier:#"ReuseChatTableViewCell"];
}
-(void)CapturePhotoImage
{
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:NO completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:NULL];
}
Thanks in Advance.!
First be sure you are using the following delegate in your view controller
<UINavigationControllerDelegate, UIImagePickerControllerDelegate>
Secondly use this line to show the ImagePicker:-
[self presentModalViewController:picker animated:YES];
Alternative Way:-
[self.view addSubview:imagePicker.cameraOverlayView]
Change the method declaration as follows
- (IBAction) CapturePhotoImage:(id)sender
{
NSLog("Called");
}
And the method call "CapturePhotoImage" as CapturePhotoImage:
[btnForCaputrePhoto addTarget:self action:#selector(CapturePhotoImage:) forControlEvents:UIControlEventTouchUpInside];
Related
for my app I want to create a custom camera overlay and create a UIImagePickerController to start recording video. (below)
- (IBAction)RecordVideo:(UIButton *)sender {
//initialise camera view
UIImagePickerController *cameraUI = [[UIImagePickerController alloc] init];
cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
cameraUI.cameraDevice = UIImagePickerControllerCameraDeviceFront;
cameraUI.showsCameraControls = NO;
cameraUI.navigationBarHidden = YES;
cameraUI.toolbarHidden = YES;
OverlayView *overlay = [[OverlayView alloc]
initWithFrame:CGRectMake(0, 0, 20,20)];
cameraUI.cameraOverlayView = overlay;
[self presentViewController:cameraUI animated:YES completion:nil];
}
as part of the cameraOverlayView I've instantiated a UIButton:
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
//clear the background color of the overlay
self.opaque = NO;
self.backgroundColor = [UIColor clearColor];
... some overlay UI stuff
UIButton *captureBtn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
UIImage *captureBtnImg = [UIImage imageNamed:#"captureBtn.png"];
[captureBtn setBackgroundImage:captureBtnImg forState:UIControlStateNormal];
captureBtn.frame = CGRectMake(self.frame.size.width/2 - 15,
430,
80,
80);
[self addSubview:captureBtn];
}
return self;
}
So how do I create an IBAction for this button which can then make the UIImagePickerController cameraUI start recording?
If somebody could also explain to me how the IBActions are called from specific buttons only that would also be amazing because that seems like black magic to me?
You can add target like this,
[captureBtn addTarget:self action:#selector(captureBtnclick:) forControlEvents:UIControlEventTouchUpInside];
and you action method shoulbe like this
-(void)captureBtnclick :(UIButton*)sender{
//handle your task on click here
}
second thing why you are adding layer on it? you can use default video recording from imagePicker by setting mediatype like
cameraUI.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];
Update accroding to comment
you can use on button click,
[picker startVideoCapture]; //in your case cameraUI i think
Update 2 :
in your .h file,
#property UIImagePickerController *cameraUI;
then in your method RecordVideo use like,
self.cameraUI = [[UIImagePickerController alloc] init];
self.cameraUI.sourceType = UIImagePickerControllerSourceTypeCamera;
//etc.....
By this way you can use camaraUI in whole class by self
hope this will help :)
I have searched similar questions for answers, but nothing I have tried has worked. When I tap on either button in my overlay view, the camera only focuses - no action is triggered. Here is my code:
Update: The previous question was answered - the code was fine, I just wasn't alerting myself in the testIfButtonResponds method. Now I am wondering how to dismiss the camera and show the captured picture in a UIImageView.
Also, the UIImageView *DisplayedPhoto was made in IB, so it has a frame.
#interface CameraViewController ()
#property UIImagePickerController *PickerController;
#property (weak, nonatomic) IBOutlet UIImageView *DisplayedPhoto;
#end
- (UIView *)createCustomOverlayView
{
// Main overlay view created
UIView *main_overlay_view = [[UIView alloc] initWithFrame:self.view.bounds];
// Clear view (live camera feed) created and added to main overlay view
// ------------------------------------------------------------------------
UIView *clear_view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height - self.HeightOfButtons)];
clear_view.opaque = NO;
clear_view.backgroundColor = [UIColor clearColor];
[main_overlay_view addSubview:clear_view];
// ------------------------------------------------------------------------
// Creates the buttons on the bottom of the view (on top of the live camera feed)
// Then adds the buttons to the main overlay view
// ------------------------------------------------------------------------
for(int i = 0; i < 2; i++) {
UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
// when a button is touched, UIImagePickerController snaps a picture
[button addTarget:self action:#selector(testIfButtonResponds) forControlEvents:UIControlEventTouchUpInside];
button.frame = CGRectMake( i * self.view.frame.size.width / 2, self.view.frame.size.height - self.HeightOfButtons, self.view.frame.size.width / 2, self.HeightOfButtons);
[button setBackgroundColor:[UIColor redColor]];
[main_overlay_view addSubview:button];
}
// ------------------------------------------------------------------------
return main_overlay_view;
}
- (void)makeCustomCameraAppear
{
self.PickerController = [[UIImagePickerController alloc] init];
self.PickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
self.PickerController.showsCameraControls = NO;
self.PickerController.delegate = self;
UIView *overlay_view = [self createCustomOverlayView];
[self.PickerController setCameraOverlayView:overlay_view];
[self presentViewController:self.PickerController animated:YES completion:NULL];
}
- (void)viewDidAppear:(BOOL)animated
{
[self makeCustomCameraAppear];
}
- (void) testIfButtonResponds
{
[self.PickerController takePicture];
[self.PickerController dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *chosen_image = info[UIImagePickerControllerEditedImage];
self.DisplayedPhoto.image = chosen_image;
[self.PickerController dismissViewControllerAnimated:YES completion:NULL];
}
I want it to flow like this I'm doing it tons of times and dosent work.
User pushes the photo button in the app and takes picture.
After taking the picture users has to input detail. sorts options comes out where user can pick 8 different default genre's, and user pushes save.
It goes back to the Home Screen and the User can see the 8 different genre in button & when pushed pictures comes out as a coverflow(flow cover) that is saved in the app. I want to make it work like the above but dosent work.
My Code is until now is:
#implementation ViewController
-(IBAction)TakePhoto {
picker = [[UIImagePickerController alloc]init];
picker.delegate = self;
[picker setSourceType: UIImagePickerControllerSourceTypeCamera ];
[self presentViewController:picker animated:YES completion:NULL];
}
-(IBAction)ChooseExisting{
picker2 = [[UIImagePickerController alloc]init];
picker2.delegate = self;
[picker2 setSourceType: UIImagePickerControllerSourceTypePhotoLibrary];
[self presentViewController:picker2 animated:YES completion:NULL];
}
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:
(NSDictionary *) info {
image = [info objectForKey:UIImagePickerControllerOriginalImage] ;
[imageview setImage:image];
[self dismissViewControllerAnimated:YES completion:NO];
}
- (void) imagePickerControllerDidCancel:(UIImagePickerController *)picker{
[self dismissViewControllerAnimated:YES completion:NULL];
}
#end
#implementation CVCLCoverFlowLayout
-(NSInteger)count {
return [self.collectionView numberOfItemsInSection:0 ];
}
-(CGSize)collectionViewContentSize{
CGSize size = self.collectionView.bounds.size;
size.width = self.count * self.cellInterval;
return size;
}
You are not saving the image you clicked in the delegate function .and when you want to use the saved image then you need to write down the code for same .:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:
(NSDictionary *) info {
image = [info objectForKey:UIImagePickerControllerOriginalImage] ;
[imageview setImage:image];
/ save the image to local storage of your application /
[self dismissViewControllerAnimated:YES completion:NO];
}
You can check the code for same over :
http://dcraziee.wordpress.com/2013/05/20/how-to-save-and-get-image-from-cache-directory/
Please share the blog if you like it.
On my app I have a cameraOverlayView over my open camera with custom controls for the camera buttons. The app allows the user to take several pictures before closing the camera, so the shutter button does not call dismissViewControllerAnimated, instead there's a close button for when you're done taking pictures.
Now, one of the buttons on the camera overlay is a gallery button to allow the user to pick a saved image instead of shooting a new one. I've tried two different approaches to make this work, both failed.
First approach
Use the same UIImagePickerController instance that is currently presenting the overlay and switch the sourceType to library. It does present the gallery then, but when a photo is tapped, I can't dismiss the galley without dismissing the whole overlay.
Second approach
Create a separate instance of UIImagePickerController, set the sourceType to gallery and attempt to call presentViewController, which then fails with the warning:
"Warning: Attempt to present on
whose view is not in the window
hierarchy!"
Does anyone have a solution for this issue? Is this even possible?
Try this~~ I think it is your goal.
#import "ViewController.h"
#interface ViewController ()
#property (nonatomic, strong) UIImagePickerController *imagePicker;
#end
#implementation ViewController
#synthesize imagePicker = _imagePicker;
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:YES];
sleep(2);
_imagePicker = [[UIImagePickerController alloc] init];
[_imagePicker setSourceType:UIImagePickerControllerSourceTypeCamera];
[_imagePicker setDelegate:self];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 50, 100, 30)];
[button setTitle:#"Library" forState:UIControlStateNormal];
[button setBackgroundColor:[UIColor darkGrayColor]];
[button addTarget:self action:#selector(gotoLibrary:) forControlEvents:UIControlEventTouchUpInside];
[_imagePicker.view addSubview:button];
[self presentViewController:_imagePicker animated:YES completion:nil];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
-(IBAction)gotoLibrary:(id)sender
{
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
[imagePicker.view setFrame:CGRectMake(0, 80, 320, 350)];
[imagePicker setSourceType:UIImagePickerControllerSourceTypeSavedPhotosAlbum];
[imagePicker setDelegate:self];
[_imagePicker presentViewController:imagePicker animated:YES completion:nil];
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[picker dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker dismissViewControllerAnimated:YES completion:nil];
}
#end
The second approach is correct.
I don't see your code, but I think that your controller hierarchy is something similar to this:
Main VC ---present---> Camera VC
so, if you call
[self presentViewController:picker animated:YES completion:^{}];
from your Main VC, you are attempting to show another VC from an "hidden" one (covered by the Camera VC).
The key is to take a reference to your camera VC (let's call it cameraVC) and do something similar from Main VC:
[cameraVC presentViewController:theOtherPicker animated:YES completion:^{}];
doing this, the "present" action is done by the Camera VC (visible) without warnings, and not by the hidden Main VC.
You could code your own custom gallery views for selecting photos and then add that to the cameraOverlayView subview hierarchy.
There must be open source projects on GitHub, which show how to make these views, somewhere. Alternatively, I happen to have released a control very similar to what you are looking for if you don't want to start from scratch.
It's quite a simple procedure really — a collection view with a datasource backed by the AssetsLibrary framework.
I would set up a capture session as follows:
- (void)setupCaptureSession
{
NSError* error = nil;
// Create the session
_captureSession = [[AVCaptureSession alloc] init];
_captureSession.sessionPreset = AVCaptureSessionPresetMedium;
AVCaptureDevice* device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput* input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
[_captureSession addInput:input];
AVCaptureVideoDataOutput* output = [[AVCaptureVideoDataOutput alloc] init];
[_captureSession addOutput:output];
// Configure your output.
dispatch_queue_t queue = dispatch_queue_create("myCameraOutputQueue", NULL);
//If you want to sebsequently use the data, then implement the delegate.
[output setSampleBufferDelegate:self queue:queue];
}
Having done that, you can create a preview layer as follows:
_previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:_captureSession];
[_captureSession startRunning];
And then add the preview layer to your view:
_myView.layer addSubLayer:_previewLayer];
Now that you have this set up, I'd add a custom image picker, such as this one: https://github.com/arturgrigor/AGImagePickerController
I present a custom camera view controller, onto which I add a "SourceTypeCamera" UIImagePickerController as a contained child view controller. My custom view controller has a button that in turn adds another UIImagePickerController instance, this one a "SourceTypePhotoLibrary".
You end up with a nested view controller hierarchy:
root/main view controller — presents:
my custom camera view controller – adds as child view controller:
either camera or photo-library UIImagePickerController
Something like this:
- (void)viewDidLoad { (id<UIImagePickerControllerDelegate,UINavigationControllerDelegate>)theDelegate {
[super viewDidLoad];
[self startImagePickerWithSourceType:UIImagePickerControllerSourceTypeCamera
delegate:self];
// configure button in camera overlay to call -pickPhotoTapped
}
- (void) pickPhotoTapped {
[self startImagePickerWithSourceType:UIImagePickerControllerSourceTypePhotoLibrary
delegate:self];
}
- (BOOL) startImagePickerWithSourceType:(UIImagePickerControllerSourceType)sourceType
delegate:(id<UIImagePickerControllerDelegate,UINavigationControllerDelegate>)theDelegate {
if (([UIImagePickerController isSourceTypeAvailable:sourceType] == NO)
|| (theDelegate == nil))
return NO;
self.cameraUI = [[UIImagePickerController alloc] init];
self.cameraUI.sourceType = sourceType;
self.cameraUI.view.frame = self.view.bounds;
self.cameraUI.delegate = theDelegate;
if (sourceType == UIImagePickerControllerSourceTypeCamera) {
self.cameraUI.allowsEditing = NO;
self.cameraUI.showsCameraControls = NO;
self.cameraUI.cameraOverlayView = [self overlayView];
}
[self addChildViewController:self.cameraUI];
[self.view addSubview:self.cameraUI.view];
[self.cameraUI didMoveToParentViewController:self];
return YES;
}
I want to open iphone saved images in my application. my application working in landscape mode. when I trying to load all saved photo from iphone library using presentModalViewController method, it will open in portrait mode. I want that in landscape mode. here is the code:
picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
picker.allowsEditing = NO;
picker.navigationBarHidden = YES;
picker.wantsFullScreenLayout = YES;
[picker setNavigationBarHidden:TRUE];
[self presentModalViewController:picker animated:NO];
NSLog(#"%#", self.view.subviews);
[picker release];
can any one help me..
Thanks in advance.
You can't. Quoth the documentation:
The UIImagePickerController class supports portrait mode only. This class is intended to be used as-is and does not support subclassing.
It's a bit more work, but you can use the AssetsLibrary framework to access the list of images and create your own image picker.
we cant get UIImagePickerController in landscape...
but we can get the images in our device into an array and display them in landscape mode and in portrait mode....itseems same like UIImagePickerController...
we should use ALAsset class and ALAssetsLibrary for this..
void (^assetEnumerator)(struct ALAsset *, NSUInteger, BOOL *) = ^(ALAsset *result, NSUInteger index, BOOL *stop)
{
if(result != NULL)
{
[assets addObject:result];
}
};
void (^assetGroupEnumerator)(struct ALAssetsGroup *, BOOL *) = ^(ALAssetsGroup *group, BOOL *stop)
{
if(group != nil)
{
[group enumerateAssetsUsingBlock:assetEnumerator];
}
[self meth];
[activity stopAnimating];
[activity setHidden:YES];
};
assets = [[NSMutableArray alloc] init];
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library enumerateGroupsWithTypes:ALAssetsGroupAlbum usingBlock:assetGroupEnumerator
failureBlock: ^(NSError *error) { NSLog(#"Failure");}];
in viewDidLoad
-(void)meth
{
NSLog(#"%i",[assets count]);
if(userOrientation==UIInterfaceOrientationPortrait || userOrientation==UIInterfaceOrientationPortraitUpsideDown)
{
NSLog(#"haii");
[scrollView removeFromSuperview];
scrollView=[[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, 320, 460)];
scrollView.backgroundColor=[UIColor whiteColor];
NSLog(#"%i",[assets count]);
for (int i = 0; i < [assets count]; i++)
{
imgBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[imgBtn setFrame:CGRectMake((i%4*80)+2,(i/4*80)+2,75,75)];
imgBtn.tag=i;
[imgBtn addTarget:self action:#selector(imageClicked:) forControlEvents:UIControlEventTouchUpInside];
ALAsset *asset=[assets objectAtIndex:i];
[imgBtn setImage:[UIImage imageWithCGImage:[asset thumbnail]] forState:UIControlStateNormal];
[scrollView addSubview:imgBtn];
}
scrollView.contentSize = CGSizeMake(320,(([assets count]/4)+1)*300 );
}
if(userOrientation==UIInterfaceOrientationLandscapeRight || userOrientation==UIInterfaceOrientationLandscapeLeft)
{
[scrollView removeFromSuperview];
scrollView=[[UIScrollView alloc]initWithFrame:CGRectMake(0, 0, 480,320)];
for (int i = 0; i < [assets count]; i++)
{
imgBtn = [UIButton buttonWithType:UIButtonTypeCustom];
[imgBtn setFrame:CGRectMake((i%6*80)+2,(i/6*80)+2,75,75)];
imgBtn.tag=i;
[imgBtn addTarget:self action:#selector(imageClicked:) forControlEvents:UIControlEventTouchUpInside];
ALAsset *asset=[assets objectAtIndex:i];
[imgBtn setImage:[UIImage imageWithCGImage:[asset thumbnail]] forState:UIControlStateNormal];
[scrollView addSubview:imgBtn];
}
scrollView.contentSize = CGSizeMake(480,(([assets count]/4)+1)*300);
}
[self.view addSubview:scrollView];
}
I have tried the code with some additions
[self.navigationController setNavigationBarHidden:YES];
[self addChildViewController:picker];
[self.view addSubview:picker.view];
picker.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
picker.view.frame = self.view.bounds;
[picker didMoveToParentViewController:self];
(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
UIImage *chosenImage = info[UIImagePickerControllerEditedImage];
self.imageView.image = chosenImage;
[picker.view removeFromSuperview];
[picker removeFromParentViewController];
}
(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
{
[picker.view removeFromSuperview];
[picker removeFromParentViewController];
}
I used following code:
[self.view addSubview:imgPicker.view];
[imgPicker viewWillAppear:YES];
[imgPicker viewDidAppear:YES];
instead of using presentModalViewController method,
[self presentModalViewController:picker animated:NO];
I tried this approach, while following the API docs more closely:
- (void)openEmbeddedImagePicker:(UIImagePickerController *)picker {
[self.navigationController setNavigationBarHidden:YES];
[self addChildViewController:picker];
[self.view addSubview:picker.view];
picker.view.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
picker.view.frame = self.view.bounds;
[picker didMoveToParentViewController:self];
}
But the video recorder's Cancel and playback buttons don't respond. Also, while the containing VC (self in the above method) restricts the orientation to landscape, rotating between the two landscape modes messes up the layout of the picker's overlay bar (on iOS 6, at least).
Does anyone have success restricting the video recorder to landscape mode?
From the UIImagePickerController Class Reference.
Important: The UIImagePickerController class supports portrait mode only. This class is intended to be used as-is and does not support subclassing. The view hierarchy for this class is private and must not be modified, with one exception. You can assign a custom view to the cameraOverlayView property and use that view to present additional information or manage the interactions between the camera interface and your code.