How do I create a modal dialog with customisable button choices just like the "take picture or video" | "choose existing" dialog on the iPhone? Those buttons aren't normal UIButton's and I'm sure they aren't hand crafted for every app out there.
It sounds like you want to use a combination of UIActionSheet and UIImagePickerController. This code shows a popup that lets the user choose to take a photo or choose an existing one, then the UIImagePickerController pretty much does everything else:
- (IBAction)handleUploadPhotoTouch:(id)sender {
mediaPicker = [[UIImagePickerController alloc] init];
[mediaPicker setDelegate:self];
mediaPicker.allowsEditing = YES;
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:#"Take photo", #"Choose Existing", nil];
[actionSheet showInView:self.view];
} else {
mediaPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:mediaPicker animated:YES];
}
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
mediaPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
} else if (buttonIndex == 1) {
mediaPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
}
[self presentModalViewController:mediaPicker animated:YES];
[actionSheet release];
}
NOTE: This assumes you have a member variable "mediaPicker" which keeps a reference to the UIImagePickerController
Related
I currently have a UIImageView and a UIImage. How do I allow the user to select one of their photos from the camera roll?
There are possible duplicates, but I've had no luck. This might possibly be because I don't hook things up in the Interface Builder.
I would like something simple like UIImage * image = [UIImage imageFromCameraRoll], but unfortunately, that's not possible (I don't think so, at least).
Try this code
It is help to you get image from cameraroll & photolibrary. using UIImagePickerViewController
if you take Picture
From camera (in both open As UINavigationcontroller).
From Gallery(for ipad open as UIpopovercontroller & for iphone open as nvigationcontroller).
First set delegate
#interface camera : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate,UIPopoverControllerDelegate>
get image from Camera
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
UIImagePickerController *imagePicker =
[[UIImagePickerController alloc] init];
imagePicker.delegate = self;
imagePicker.sourceType =
UIImagePickerControllerSourceTypeCamera;
imagePicker.mediaTypes = [NSArray arrayWithObjects:
(NSString *) kUTTypeImage,
nil];
imagePicker.allowsEditing = YES;
imagePicker.wantsFullScreenLayout = YES;
[self presentViewController:imagePicker animated:YES completion:nil];
newMedia = YES;
iscamera = 0;
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error to access Camera"
message:#""
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
Get image from Gallery
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary])
{
UIImagePickerController *_picker=nil;
if (popoverController) {
[popoverController dismissPopoverAnimated:NO];
}
_picker = [[UIImagePickerController alloc] init];
_picker.delegate = self;
_picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
_picker.wantsFullScreenLayout = YES;
//[popoverController presentPopoverFromBarButtonItem:sender
// permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
[self presentViewController:_picker animated:YES completion:nil];
} else
{
popoverController = [[UIPopoverController alloc] initWithContentViewController:_picker];
[popoverController setDelegate:self];
[popoverController presentPopoverFromRect:btn.frame
inView:self.view
permittedArrowDirections:UIPopoverArrowDirectionLeft
animated:YES];
}
}
else
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Error access photo library"
message:#"your device non support photo library"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
Both Result you get in Delegate Method
-(void)imagePickerController:(UIImagePickerController *)picker
didFinishPickingMediaWithInfo:(NSDictionary *)info
{
// write your code here ........
}
Use UIImagePickerController, see the Apple docs.
Select the source type:
#property (nonatomic) UIImagePickerControllerSourceType sourceType
From on on these:
UIImagePickerControllerSourceTypePhotoLibrary,
UIImagePickerControllerSourceTypeCamera,
UIImagePickerControllerSourceTypeSavedPhotosAlbum
I have 3 buttons in my UIActionsheet.
I want one cancel button at the bottom of it.
I also want that all of the buttons should be able to dismiss UIActionsheet.
Currently, none of them does the job for me.
Here is how I display it:
UIActionSheet *actionSheet = nil;
NSArray *otherButtons = nil;
otherButtons = [NSArray arrayWithObjects:#"Button1", #"Button2", #"Button3",
nil];
actionSheet = [[UIActionSheet alloc] initWithTitle:title
delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:nil, nil];
for( NSString *btntitle in otherButtons)
{
[actionSheet addButtonWithTitle:btntitle];
}
[actionSheet addButtonWithTitle:#"Cancel"];
actionSheet.cancelButtonIndex = actionSheet.numberOfButtons - 1;
actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
[actionSheet showInView:self.view];
In my delegate, I do this:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
//some code
[actionSheet dismissWithClickedButtonIndex:buttonIndex animated:YES];
}
But it does not dismiss. I do not want to change my design and position of any buttons.
What should I do?
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
[actionSheet dismissWithClickedButtonIndex:buttonIndex animated:YES];
[self performSelector:#selector(OtherOperations) withObject:nil afterDelay:0.0];
}
-(void)OtherOperations{ //some code
}
Be careful when opening an action sheet from a lpgr. Only open it on "Began", not again on "Ended".
- (void) handleLongPress:(UILongPressGestureRecognizer *)gestureRecognizer
{
CGPoint p = [gestureRecognizer locationInView:self.tblYourVids];
if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
NSIndexPath *indexPath = [self.aTable indexPathForRowAtPoint:p];
if (indexPath == nil)
NSLog(#"long press on table view but not on a row");
else {
NSLog(#"long press on table view at row %d", indexPath.row);
self.selectedCell = [self.aTable cellForRowAtIndexPath:indexPath];
DLog(#"open action sheet only once");
[self showActionSheet];
}
} else if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
// eat this one
}
}
you have to add this to yours .h file.
<UIActionSheetDelegate>
Also add this line to yours .m file.
actionSheet.delegate = self;
Let me know, this is working or not. If works, accept it as right answer
just try to use the below code.it will automatically dismiss.
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:#""
delegate:self
cancelButtonTitle:#"cancel"
destructiveButtonTitle:#"Printer"
otherButtonTitles: nil];
[sheet showInView:self.view];
[sheet release];
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
}
let me know whether it is working or not
Happy Coding!!!!!
This is not the right way to cancel UIActionSheet firstly you have to disable to default UIActionSheet by javascipt
and go through this web
http://www.icab.de/blog/2010/07/11/customize-the-contextual-menu-of-uiwebview/
Hi all i'm new iphone developer,
I have problem while open the uiimagepickercontroller.
I have option take the photo and open gallery in popoverview to take the photo and open the camera that time hide the popoverview and open gallery hide the popover and open the imagepicker from parent view controller imagepicker should not open from popover view controller.
please share your ideas.
// For opening camera
-(void)btnCameraClicked {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
imgPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:imgPicker animated:YES];
}
else {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"" message:#"Camera is not Available" delegate:self cancelButtonTitle:nil otherButtonTitles:#"Ok",nil];
[alert show];
[alert release];
}
}
// For opening image picker controller
-(void)btnGalleryClicked {
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:imgPicker animated:YES];
}
else {
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:nil message:#"Photos are not available" delegate:self cancelButtonTitle:nil otherButtonTitles:#"Ok",nil];
[alert show];
[alert release];
}
}
After this you can use ImagePicking Methods like :
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
You can use UIPopoverControllerDelegate method
-(void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController;
I have 2 UIBarButoon in a UIToolbar. Each has an IBAction to launch their own UIActionSheets.
Right now, if I present one, then click the other UIBarButton, the other ActionSheet gets presented as well, so I have two on the screen and they are overlapping. I want one to dismiss when the other is presented, etc.
I have this code now:
- (IBAction)showFirstActionSheet:(id)sender
{
if (!self.eRXActionSheet)
{
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:#"eRX Menu" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"New eRX", #"eRX Refills", nil];
sheet.actionSheetStyle = UIActionSheetStyleBlackOpaque;
self.eRXActionSheet = sheet;
[sheet release];
[self.eRXActionSheet showFromBarButtonItem:sender animated:YES];
return;
}
[self.eRXActionSheet dismissWithClickedButtonIndex:self.eRXActionSheet.cancelButtonIndex animated:YES];
self.eRXActionSheet = nil;
}
- (IBAction)showSecondActionSheet:(id)sender
{
if (!self.actionSheet)
{
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:#"Action Menu" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Help", #"Lock", #"Log Out", nil];
sheet.actionSheetStyle = UIActionSheetStyleBlackOpaque;
self.actionSheet = sheet;
[sheet release];
[self.actionSheet showFromBarButtonItem:sender animated:YES];
return;
}
[self.actionSheet dismissWithClickedButtonIndex:self.actionSheet.cancelButtonIndex animated:YES];
self.actionSheet = nil;
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (actionSheet == self.eRXActionSheet)
{
if (buttonIndex == 0)
{
[self erxButtonClicked];
}
else if (buttonIndex == 1)
{
[self erxRefillButtonClicked];
}
}
else
{
if (buttonIndex == 0)
{
[self helpButtonClicked];
}
else if (buttonIndex == 1)
{
[self lockButtonClicked];
}
else if (buttonIndex == 2)
{
[self logOut];
}
}
}
In your code, before creating an action sheet, your are checking if the action sheet to be displayed is not nil. Logically, this will always evaluate to true.
Rather you should check if the other action sheet is not nil. If so, dismiss it and create the new one.
-(void)buttonForActionSheet1Clicked {
if (actionSheet2 != nil) {
// dismiss it
}
// show actionSheet1
}
-(void)buttonForActionSheet2Clicked {
if (actionSheet1 != nil) {
// dismiss it
}
// show actionSheet2
}
Alternatively, you can force the user to dismiss the present action sheet with the cancel button first by disabling the other button in the toolbar.
Call dismissWithClickedButtonIndex:animated: on the actionsheet you want dismissed.
E.g. in showFirstActionSheet add this line to dismiss the other:
if(self.actionSheet) [self.actionSheet dismissWithClickedButtonIndex:<indexofCancelButton> animated:YES];
I am presenting a UIActionSheet from a UIBarButtonItem. I want the action sheet to dismiss when I click the bar button again, instead it is creating a new one each time layered on top of each other. Any ideas?
- (IBAction)actionButtonClicked:(id)sender
{
UIActionSheet *popupQuery = [[UIActionSheet alloc] initWithTitle:#"Action Menu" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Help", #"Lock", nil];
popupQuery.actionSheetStyle = UIActionSheetStyleBlackOpaque;
[popupQuery showFromBarButtonItem:sender animated:YES];
[popupQuery release];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
[self erxButtonClicked];
}
else if (buttonIndex == 1)
{
[self erxRefillButtonClicked];
}
}
I would declare a #property for popupQuery on my class and use it to keep track of the action sheet.
- (IBAction)actionButtonClicked:(id)sender
{
// If self.popupQuery is not nil, it means the sheet is on screen and should be dismissed. The property is then set to nil so a new sheet can be created next time.
if (self.popupQuery)
{
[self.popupQuery dismissWithClickedButtonIndex:self.popupQuery.cancelButtonIndex animated:YES];
self.popupQuery = nil;
return;
}
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:#"Action Menu" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Help", #"Lock", nil];
sheet.actionSheetStyle = UIActionSheetStyleBlackOpaque;
sheet.delegate = self;
self.popupQuery = sheet;
[sheet release];
[self.popupQuery showFromBarButtonItem:sender animated:YES];
}
// Implementing this method to be notified of when an action sheet dismisses by means other than tapping the UIBarButtonItem. We set the property to nil to prepare for lazy instantiation next time.
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
self.popupQuery = nil;
}