I have an app that uses the UIImagePickerController to take a picture. The problem is that I only want the camera option to be available and I understand that I need to hide the standard controls:
cameraUI.showsCameraControls=NO;
and use a cameraOverlayView to provide my own controls. I have had a look at Apple's PhotoPicker project already and my initial problem is how do I get an Overlay object onto my storyboard? I can't find such an object in the library.
Here is the code :
toolBar=[[UIToolbar alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height-54, self.view.frame.size.width, 55)];
toolBar.barStyle = UIBarStyleBlackOpaque;
NSArray *items=[NSArray arrayWithObjects:
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(cancelPicture)],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:#selector(shootPicture)],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
nil];
[toolBar setItems:items];
// create the overlay view
overlayView = [[OverlayView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height-44)];
// important - it needs to be transparent so the camera preview shows through!
overlayView.opaque=NO;
overlayView.backgroundColor=[UIColor clearColor];
// parent view for our overlay
UIView *cameraView=[[UIView alloc] initWithFrame:self.view.bounds];
[cameraView addSubview:overlayView];
[cameraView addSubview:toolBar];
imagePickerController = [[UIImagePickerController alloc] init];
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == NO){
NSLog(#"Camera not available");
return;
}
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.delegate = self;
// hide the camera controls
imagePickerController.showsCameraControls=NO;
imagePickerController.wantsFullScreenLayout = YES;
[imagePickerController setCameraOverlayView:cameraView];
[self presentViewController:imagePickerController animated:YES completion:nil];
Declare this in your header file :
UIImagePickerController * imagePickerController;
UIToolbar *toolBar;
OverlayView *overlayView;
Add this OverlayView.h and .m Class from Apples PhotoPicker.
Actions for capturing photo using custom camera button:
-(void) shootPicture {
[imagePickerController takePicture];
}
- (IBAction)cancelPicture {
[self dismissViewControllerAnimated:YES completion:nil];
}
Output will come like this below attached screenshot (I have added a capture button and cancel button in custom overlay view):
Happy Coding :)
Here is my code. If you want the camera to appear as soon as the view controller opens, make sure you initialize the UIImagePickerController in viewDidAppear like I did (viewDidLoad does not work).
#interface CameraViewController ()
#property UIImagePickerController *PickerController;
#property CGFloat HeightOfButtons;
#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 two red buttons on the bottom of the view (on top of the live camera feed)
// Then adds the buttons to the main overlay view
// You can, of course, customize these buttons however you want
// ------------------------------------------------------------------------
for(int i = 0; i < 2; i++) {
self.HeightOfButtons = 100;
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];
}
great information. To add a little to what Raghu did:
up top:
UIImagePicker *_imagePicker;
//inside your take a picture method
UIToolbar *toolBar=[[UIToolbar alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 100)];
toolBar.barStyle = UIBarStyleBlackOpaque;
NSArray *items=[NSArray arrayWithObjects:
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(cancelPicker)],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:#selector(shootPicture)],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil],
nil];
[toolBar setItems:items];
toolBar.backgroundColor=[UIColor blackColor];
UIImageView *tp=[[UIImageView alloc]initWithFrame:CGRectMake(0, self.view.frame.size.height-100, self.view.frame.size.width, 100)];
tp.userInteractionEnabled=YES;
tp.backgroundColor=[UIColor blackColor];
[tp addSubview:toolBar]; //add the toolbar to the uiimageview
_imagePicker=[[UIImagePickerController alloc]init];
_imagePicker.sourceType=UIImagePickerControllerSourceTypeCamera;
_imagePicker.delegate = self;
_imagePicker.showsCameraControls=NO; //we will make custom controls.
[_imagePicker.view addSubview:tp];
-(void)cancelPicker{
//get rid of the image picker
[self dismissViewControllerAnimated:YES completion:nil]; //dismiss uiimagepicker
_imagePicker=nil;
}
//take the picture, it will then go directly to - (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info method
-(void)shootPicture{
[_imagePicker takePicture];
}
Related
i have a uipickerivew in uitablview prototype cell, i want to hide only when done button pressed. please help me.
here is my code for how i create uipickeriview and done button.
self.pickerView = [[UIPickerView alloc] initWithFrame:(CGRect){{0, 0}, 330, 200}];
self.pickerView.delegate = self;
self.pickerView.dataSource = self;
self.pickerView.center = (CGPoint){160, 640};
self.pickerView.hidden = YES;
self.pickerView.backgroundColor =[UIColor whiteColor];
[self.view addSubview:self.pickerView];
UIToolbar *toolBar= [[UIToolbar alloc] initWithFrame:CGRectMake(0,0,320,44)];
[toolBar setBarStyle:UIBarStyleBlackOpaque];
UIBarButtonItem *flex = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *barButtonDone = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(pickerDoneClicked)];
toolBar.items = #[barButtonDone];
toolBar.items = #[flex, barButtonDone];
barButtonDone.tintColor = [UIColor lightGrayColor];
[_pickerView addSubview:toolBar];
-(void) pickerDoneClicked {
[_pickerView resignFirstResponder];
}
It is better to rather than create and remove each time, create your pickerview once in view did load and then in your cell do:
[_pickerView becomeFirstResponder];
(to show it like a keyboard animated in).
You can then create a pickerDoneClicked method (that is called when Done is tapped) to call resignFirstResponder on your pickerview (to animate it away):
-(void) pickerDoneClicked {
[_pickerView resignFirstResponder];
}
just add below IBAction method and call removefromsuperview method,
-(void)pickerDoneClicked{
[self.pickerView removeFromSuperview];}
As you are already adding again everytime, you can directly remove it from superview and adding again.
After selecting a value using picker view you can implement this method.Add a toolbar with done button and give action to done button
- (IBAction)doneClicked:(id)sender {
[yourTextfield resignFirstResponder];
}
this method is used in the case , when selecting a value to the textfield with picker as input.
- (void)viewDidLoad {
self.pickerView = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 0, 330, 200)];
self.pickerView.delegate = self;
self.pickerView.dataSource = self;
self.pickerView.backgroundColor =[UIColor whiteColor];
[self.view addSubview:self.pickerView];
UIToolbar *toolBar= [[UIToolbar alloc] initWithFrame:CGRectMake(0,0,320,44)];
[toolBar setBarStyle:UIBarStyleBlackOpaque];
UIBarButtonItem *barButtonDone = [[UIBarButtonItem alloc] initWithTitle:#"Done"
style: UIBarButtonItemStylePlain
target:self
action:#selector(pickerDoneClicked:)];
UIBarButtonItem *flex = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
toolBar.items = #[flex, barButtonDone];
barButtonDone.tintColor = [UIColor lightGrayColor];
[self.view addSubview:toolBar];
}
-(IBAction)pickerDoneClicked:(id)sender
{
pickerView.hidden = YES;
}
Inside the didiSelectRow method add this line of code:
self.view.endEditing(true)
I've got a UIPickerView that has a UIToolbar attached to it on the parent view's load with this code:
- (void)viewDidLoad {
[super viewDidLoad];
self.itemSortPicker.hidden = false;
pickerData = #[#"Name",#"Item Level",#"Crafting Level",#"Profit",#"Profit Percentage",#"Sell Price",#"Buy Price",#"Supply",#"Demand",#"Rarity"];
self.itemSortPicker.dataSource = self;
self.itemSortPicker.delegate = self;
UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
pickerToolbar.barStyle = UIBarStyleDefault;
[pickerToolbar sizeToFit];
[pickerToolbar setFrame:CGRectMake(0, -pickerToolbar.bounds.size.height, 320, 44)];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(pickerCancel)];
[barItems addObject:cancelBtn];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItems addObject:flexSpace];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(pickerDone)];
[barItems addObject:doneBtn];
[pickerToolbar setItems:barItems animated:YES];
CGRect pickerRect = self.itemSortPicker.bounds;
self.itemSortPicker.bounds = pickerRect;
self.itemSortPicker.frame = CGRectMake(0, 44, 320, 216);
[self.itemSortPicker addSubview:pickerToolbar];
}
Now the problem is, when I tap on either the 'done' or 'cancel' buttons, the associated method doesn't trigger. The method doesn't take any parameters and just does an NSLog action. The PickerView isn't taking focus from the bar because when I tap and drag on the buttons, the PickerView doesn't change.
The problem is that the UIToolbar isn't entirely inside the frame of the UIPickerView. As your code is written, although UIToolbar is a subview of UIPickerView, the toolbar is -pickerToolbar.bounds.size.height above the UIPickerView:
[pickerToolbar setFrame:CGRectMake(0, -pickerToolbar.bounds.size.height, 320, 44)];
so you're unable to interact with its buttons because it's hanging off the edge of its superview's frame. For example, if you changed the pickerToolbar frame like so:
[pickerToolbar setFrame:CGRectMake(0, 0, 320, 44)];
you should be able to interact with it.
If you need this specific placement -pickerToolbar.bounds.size.height above the UIPickerView though, I suggest not adding it as a subview to UIPickerView and placing it appropriately as a subview to UIPickerView's superview instead. In general, if you need to interact with a subview it needs to be entirely within its superview's frame.
Edit: In this case, if you're going to instead add the toolbar to the superview, like so:
[self.view addSubview:pickerToolbar];
I suggest trying out this frame to maintain your original placement:
[pickerToolbar setFrame:CGRectMake(self.itemSortPicker.frame.origin.x, self.itemSortPicker.frame.origin.y - pickerToolbar.bounds.size.height, 320, 44)];
(To calculate this new frame, I've added the UIPicker's x and y origin values to the frame's x and y to adjust for the change in the view's coordinate system.)
I'm not sure of wether the problem is because of the button or the toolbar itself nor the pickerview but a better way of doing this is to do it all programmatically and you have to remove the pickerview from the view:
- (void)viewDidLoad {
[super viewDidLoad];
pickerData = #[#"Name",#"Item Level",#"Crafting Level",#"Profit",#"Profit Percentage",#"Sell Price",#"Buy Price",#"Supply",#"Demand",#"Rarity"];
UIPickerView *itemSortPicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 0, 320, 162)];
itemSortPicker.dataSource = self;
itemSortPicker.delegate = self;
itemSortPicker.showsSelectionIndicator = YES;
UIBarButtonItem *cancelBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(pickerCancel)];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone target:self action:#selector(pickerDone)];
UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
[pickerToolbar setBarStyle:UIBarStyleDefault];
[pickerToolbar sizeToFit];
[toolBar setItems:#[cancelBtn,flexSpace,doneBtn]];
BlaBlaTextField.delegate = self;
BlaBlaTextField.inputView = itemSortPicker;
BlaBlaTextField.inputAccessoryView = pickerToolbar;
}
And not to forget your pickerCancel and pickerDone functions, and of course the delegate methods of your itemSortPicker.
I hope that solves your problem.
I have created a Toolbar button and given action() to navigate to other ViewController.But the code is not working for Navigation.And not able to assign a image to the button.How can i solve this?
- (void)viewDidLoad {
[super viewDidLoad];
[self.navigationController setToolbarHidden:NO];
UIToolbar *toolbar = [[UIToolbar alloc] init];
toolbar.frame = CGRectMake(0, 418, 320, 44);
[self.view addSubview:toolbar];
[toolbar release];
UIBarButtonItem *customItem = [[UIBarButtonItem alloc] initWithTitle:#"update" style:UIBarButtonItemStyleBordered target:self action:#selector(updateAddress:)];
NSMutableArray *toolbarItems = [NSMutableArray arrayWithObjects:customItem, nil];
[toolbar setItems:toolbarItems animated:NO];
}
-(void)updateAddress{
DisplayMapViewController *updateView=[[DisplayMapViewController alloc]init];
UINavigationController *navi=[[UINavigationController alloc]initWithRootViewController:updateView];
[self.navigationController popToViewController:navi animated:YES];
}
First you should set the selector right, you should take out the : from the selector because you don't have parameters for the updateAddress method
should be like this
UIBarButtonItem *customItem = [[UIBarButtonItem alloc] initWithTitle:#"update" style:UIBarButtonItemStyleBordered target:self action:#selector(updateAddress)];
Then You need to initialize the DisplayMapViewController with its NibName
DisplayMapViewController *updateView=[[DisplayMapViewController alloc]initWithNibName:#"DisplayMapViewController" bundle:nil];
and then just pop to the view you are intended to.
[self.navigationController popToViewController:updateView animated:YES];
if you have already rootViewController then you could just popToRootViewController
In my iPad app, i add navigation bar and tool bar manually.
I also add scroll view and image view by coding.
My problem is i can see both navigation bar and tool bar.
I can click button on navigation bar.
But, i can't click bar button on tool bar.
How can i do it?
This is my code.
- (void)viewDidLoad
{
[super loadView];
self.view.backgroundColor = [UIColor grayColor];
UIScrollView *ScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 44, self.view.frame.size.width, self.view.frame.size.height)];
ScrollView.pagingEnabled = YES;
NSInteger numberOfViews = 4;
for (int i = 0; i < numberOfViews; i++) {
CGFloat xOrigin = i * self.view.frame.size.width;
// Create a UIImage to hold Info.png
UIImage *image1 = [UIImage imageNamed:#"Image-001.jpg"];
UIImage *image2 = [UIImage imageNamed:#"Image-002.jpg"];
UIImage *image3 = [UIImage imageNamed:#"Image-003.jpg"];
UIImage *image4 = [UIImage imageNamed:#"Image-004.jpg"];
NSArray *images = [[NSArray alloc] initWithObjects:image1,image2,image3,image4,nil];
UIImageView *ImageView = [[UIImageView alloc] initWithFrame:CGRectMake(xOrigin, 0, self.view.frame.size.width, self.view.frame.size.height-88)];
[ImageView setImage:[images objectAtIndex:i]];
[ScrollView addSubview:ImageView];
}
ScrollView.contentSize = CGSizeMake(self.view.frame.size.width * numberOfViews, self.view.frame.size.height);
[self.view addSubview:ScrollView];
}
I dont Know what is your exact problem, Because your displayed code is not related to UIToolBar.
But Following code i added two UIBarButton with flexSpace.
you can add UIBarButton as you want
UIToolbar *Toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
Toolbar = UIBarStyleBlackTranslucent;
[Toolbar sizeToFit];
NSMutableArray *barItems = [[NSMutableArray alloc] init];
UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
[barItems addObject:flexSpace];
[flexSpace release];
UIBarButtonItem *btnCancel = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStyleBordered target:self action:#selector(Cancel)];
[barItems addObject:btnCancel];
UIBarButtonItem *btnDone = [[UIBarButtonItem alloc] initWithTitle:#"Done" style:UIBarButtonItemStyleBordered target:self action:#selector(done)];
[barItems addObject:btnDone];
[Toolbar setItems:barItems animated:YES];
Following Method is call when tapped on bar Button
-(void)Cancel
{
// Write Code for Cancel Method
}
-(void)done
{
// Write Code for Done Method
}
This code might helpful in your own case.
Thanks :)
Thanks everybody. I can solve my problem.
I change my code.
UIScrollView *ScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 44, self.view.frame.size.width, self.view.frame.size.height)];
To this.
UIScrollView *ScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 44, self.view.frame.size.width, self.view.frame.size.height-88)];
I have tested my app using instrument and it show the following leak.
When I double click on the CameraVC in the stack trace it refer to the following line into my code.
this happen when I call the camera, I call it using the following code:-
- (IBAction) getCamera
{
// set up our camera overlay view
// tool bar - handy if you want to be able to exit from the image picker...
UIToolbar *toolBar=[[UIToolbar alloc] initWithFrame:CGRectMake(0, 480-44, 320, 44)];
UIBarButtonItem *spaceItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil] autorelease];
UIBarButtonItem *spaceItem1 = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil] autorelease];
UIBarButtonItem *cancelItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(cancelPickingImag)] autorelease];
UIBarButtonItem *cameraItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCamera target:self action:#selector(finishedAugmentedReality)] autorelease];
spaceItem.width = 2.0;
spaceItem1.width = 55.0;
NSArray *items=[NSArray arrayWithObjects:spaceItem,cancelItem,spaceItem1,cameraItem,nil];
[toolBar setItems:items];
// create the overlay view
overlayView=[[OverlayView alloc] initWithFrame:CGRectMake(0, 300, 320, 480-44)];
// important - it needs to be transparent so the camera preview shows through!
overlayView.opaque=NO;
overlayView.backgroundColor=[UIColor clearColor];
// parent view for our overlay
UIView *parentView=[[UIView alloc] initWithFrame:CGRectMake(0,0,320, 480)];
[parentView addSubview:overlayView];
[parentView addSubview:toolBar];
[parentView addSubview:lbl];
[parentView addSubview:overlayGraphicView];
// configure the image picker with our overlay view
//UIImagePickerController *picker=[[UIImagePickerController alloc] init];
if ([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeCamera])
{
imagePicker = [[UIImagePickerController alloc] init];
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
// hide the camera controls
imagePicker.showsCameraControls=NO;
imagePicker.delegate = self;
//imagePicker.allowsImageEditing = NO;
// and put our overlay view in
imagePicker.cameraOverlayView=parentView;
}
else
{
imagePicker = [[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
imagePicker.mediaTypes = [NSArray arrayWithObjects:
(NSString *) kUTTypeImage,
nil];
imagePicker.allowsEditing = NO;
}
[self presentModalViewController:imagePicker animated:YES];
//Free memory
[imagePicker release];//,imagePicker =nil;
[parentView release], parentView=nil;
[overlayGraphicView release], overlayGraphicView= nil;
[lbl release], lbl=nil;
[overlayView release];//, overlayView =nil;
[toolBar release], toolBar=nil;
}
any help is highly appreciated
Thanks
parentView is being created with [alloc [init...]], meaning it's retained. Then you assign it to the cameraOverlayView property of imagePicker, meaning it gets retained again. You need to release it after you do that assignment.
(This is almost certainly the cause of the "leak", but would not cause a "crash". You say you're having a crash but don't describe that at all.)