Use this code to open an actionsheet.
On iPhone works perfectly, but on iPad it crashes. I think it's because of arm64. Probably I have to transform Actionsheet into a popover.
How do I change this code?
- (void)pushedNewBtn
{
UIActionSheet *sheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Camera", #"Photo Library", nil];
[sheet showInView:self.view.window];
}
For the correct use of UIAlertViews you need to use the delegate methods to respond to a button being pressed.
In your header file you need the following
#interface ViewController : UIViewController <UIAlertViewDelegate>
You have correctly set the delegate of your UIAlertView variable using the following line delegate:self.
Now, once you press a button in the UIAlertView, the delegate will call the following method
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
You can then respond to button presses in there with code that looks something similar to this
switch (buttonIndex) {
case 0:
//Cancel button code goes here if needed
break;
case 1:
//First 'other' button code goes here
break;
case 2:
//second 'other' button code goes here
break;
default:
break;
}
I hope this helps
this is the working result:
- (void)pushedNewBtn {
UIAlertView *sheet = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Camera", #"Photo Library", nil];
[sheet show];
}
- (void)libraryButton {
UIImagePickerController *pickerLibrary = [[UIImagePickerController alloc] init];
pickerLibrary.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
pickerLibrary.delegate = self;
[self presentModalViewController:pickerLibrary animated:YES];
}
- (void)cameraButton {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentViewController:picker animated:YES completion:NULL];
}
#pragma mark- alertView delegate PICKER
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (buttonIndex) {
case 0:
return;
break;
case 1:
[self cameraButton];
break;
case 2:
[self libraryButton];
break;
default:
break;
}
}
but now i have new problem,
I want to INSERT A New alertviev but does not work
- (void)pushedSaveBtn {
UIAlertView *sheet2 = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Save", nil];
[sheet2 show];
}
- (void)savemeButton {
//codice da inserire
}
#pragma mark- alertView2 delegate SAVER
- (void)alertView2:(UIAlertView *)alertView2 clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (buttonIndex) {
case 0:
return;
break;
case 1:
[self savemeButton];
break;
default:
break;
}
}
Related
I am developing an iOS 7 app in xcode 5. I am using the camera functionality. When the user presses the camera button in my app, I want to give him a choice: take a new picture or choose a picture from the "photostream". I want to show a popup with the choice like "WhatsApp" does, or like the Apple Message app.
I thought; I create an Table View Controller with a section and three cells: take a picture, choose from "photostream" and cancel. I set this section at the bottom of the Table View and make the background transparent. But is does not work ;)
I also searched on Google, but I did not found anything that could help me.
Can anyone tell me how I could do it?
Try this. You have to use UIActionSheetDelegate and UIImagePickerControllerDelegate
- (IBAction)changePhotoButtonPressed:(id)sender {
UIActionSheet *actionSheet=[[UIActionSheet alloc] initWithTitle:#"MY APP"
delegate:self
cancelButtonTitle: nil
destructiveButtonTitle: nil
otherButtonTitles:#"Take From Camera",#"Select From Library", #"Cancel", nil];
actionSheet.actionSheetStyle = UIActionSheetStyleBlackOpaque;
actionSheet.destructiveButtonIndex=2;
[actionSheet showInView:[UIApplication sharedApplication].keyWindow];
}
UIActionSheet Delegate
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex==0) {
[self takePictureFromCamera];
}
else if (buttonIndex==1) {
[self pickImageFromLibrary];
}
}
Other Methods:
-(void) pickImageFromLibrary
{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypePhotoLibrary]) {
UIImagePickerController* imgPicker=[[UIImagePickerController alloc] init];
self.imagePicker = imgPicker;
//UI Customization
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
[[self.imagePicker navigationBar] setTintColor:[UIColor whiteColor]];
}
self.imagePicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
self.imagePicker.delegate = self;
[self presentViewController:self.imagePicker animated:YES completion:nil];
} else {
NSLog(#"Attempted to pick an image with illegal source type '%d'", UIImagePickerControllerSourceTypePhotoLibrary);
}
}
-(void) takePictureFromCamera
{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
UIImagePickerController* imgPicker=[[UIImagePickerController alloc] init];
self.imagePicker = imgPicker;
self.imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
self.imagePicker.delegate = self;
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
[[self.imagePicker navigationBar] setTintColor:[UIColor whiteColor]];
}
[self presentViewController:self.imagePicker animated:YES completion:nil];
} else {
NSLog(#"Attempted to pick an image with illegal source type '%d'", UIImagePickerControllerSourceTypePhotoLibrary);
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:#"MY APP" message:#"CAMERA_NOT_AVAILABLE" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
}
}
You should use an UIImagePickerController and set its type to either UIImagePickerControllerSourceTypeCamera or UIImagePickerControllerSourceTypePhotoLibrary.
And for the popup with the choices, use an UIActionSheet.
You can have a look at this sample code form Apple for the UIImagePickerController:
https://developer.apple.com/library/ios/samplecode/PhotoPicker/Introduction/Intro.html
I got a error on Presenting FDTake (Github-Link) FROM a PRESENTED TableViewController:
Warning: Attempt to present UIImagePickerController: 0x14454a880 on NavigationViewController: 0x14452f900 whose view is not in the window hierarchy!
NavigationViewController is a subclass of UINavigationController. It's from REMenu (https://github.com/romaonthego/REMenu).
Any Idea how I can solve it? I already wrote a Issue to the repository but nobody answered, so I thought maybe you guys know why.
I have never used that library though I can share my code for the same functionality with you. Feel free to use it whereever you were using FDTake. Don't forget to set Actionsheet and UIImagePickerController Delegates.
-(IBAction)chooseProfilePicture:(id)sender
{
UIActionSheet *filterActionSheet = [[UIActionSheet alloc] initWithTitle:#"Select Operation"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles:#"Choose from gallery", #"Take Photo", nil];
[filterActionSheet showInView:self.view];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
UIImagePickerController *imgPicker = [[UIImagePickerController alloc] init];
imgPicker.delegate = self;
imgPicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
switch (buttonIndex) {
case 0:
[self.navigationController presentModalViewController:imgPicker animated:YES];
break;
case 1:
if ([UIImagePickerController isSourceTypeAvailable:
UIImagePickerControllerSourceTypeCamera])
{
imgPicker.sourceType =
UIImagePickerControllerSourceTypeCamera;
imgPicker.mediaTypes = #[(NSString *) kUTTypeImage];
imgPicker.allowsEditing = NO;
[self presentViewController:imgPicker
animated:YES completion:nil];
//_newMedia = YES;
}
break;
default:
break;
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)img editingInfo:(NSDictionary *)editInfo
{
[picker dismissModalViewControllerAnimated:YES];
//Do what you want with the captured/selected image
}
It's that simple. Not really a need for using third party libs for that. Not an answer to your question but it is relevant in some fashion.
I want to add a pop up when someone pushes the "Back" button of my iOS App, to ask the user if he really wants to come back. Then, depending on the user's response, I would like to undo the action or proceed. I've tried to add the code in the viewWillDisappear function of my view and then write the proper delegate but it doesn't work, because it always change the view and then show the pop up. My code is:
-(void) viewWillDisappear:(BOOL)animated {
_animated = animated;
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
UIAlertView *alert_undo = [[UIAlertView alloc] initWithTitle:#"UIAlertView"
message:#"You could be loosing information with this action. Do you want to proceed?"
delegate:self
cancelButtonTitle:#"Go back"
otherButtonTitles:#"Yes", nil];
[alert_undo show];
}
else [super viewWillDisappear:animated];
}
And the delegate implementation is:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"Yes"])
{
[super viewWillDisappear:_animated];
}
}
This is not working at all. Does anybody now a better way to do it or what could be wrong?
Thank you very much,
Once -viewWillDisappear: is called, there's no stopping your viewController from disappearing.
You should ideally, override the navigationBar's back button and in it's method, display the alert (the rest being pretty much the same)
- (void)viewDidLoad
{
//...
UIBarButtonItem *bbtnBack = [[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(goBack:)];
[self.navigationItem setBackBarButtonItem: bbtnBack];
}
- (void)goBack:(UIBarButtonItem *)sender
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Alert"
message:#"...Do you want to proceed?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch(buttonIndex) {
case 0: //"No" pressed
//do something?
break;
case 1: //"Yes" pressed
//here you pop the viewController
[self.navigationController popViewControllerAnimated:YES];
break;
}
}
NOTE: Don't forget to declare <UIAlertViewDelegate> in the .h file of this viewController
Thanks for your answer, #staticVoidMan! I finally used your code with some modifications. The back button cannot be modified so one should create a additional button and hid the standard one. The only problem is the style of the new "Back" button, which is not equal than the standard one. The final code is:
- (void)viewDidLoad
{
self.navigationItem.hidesBackButton = YES;
UIBarButtonItem *bbtnBack = [[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(goBack:)];
self.navigationItem.leftBarButtonItem = bbtnBack;
}
- (void)goBack:(UIBarButtonItem *)sender
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Alert"
message:#"...Do you want to proceed?"
delegate:self
cancelButtonTitle:#"No"
otherButtonTitles:#"Yes", nil];
[alert show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch(buttonIndex) {
case 0: //"No" pressed
//do something?
break;
case 1: //"Yes" pressed
//here you pop the viewController
[self.navigationController popViewControllerAnimated:YES];
break;
}
}
Background: On iPad, I have a button which when tapped, showed a UIActionSheet. This action sheet has 2 options, camera and gallery. Camera when tapped, pulled up a camera and everything works fine. Gallery when tapped, suppose to show a popover with user's photos in it.
Problem: On iPad, UIActionSheet acts like a popover. Which when presenting, another popover cannot come into view. Error:Terminating app due to uncaught exception 'NSGenericException', reason: '-[UIPopoverController dealloc] reached while popover is still visible.
My code:
Setting Action Sheet
- (void)imageButtonTapped:(UIButton *)sender
{
if (_commentObject.image){
_actionSheet = [[UIActionSheet alloc] initWithTitle:#"Action" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:#"Remove" otherButtonTitles:nil];
_actionSheet.tag = ACTION_IMAGE_REVIEW_TAG;
}else{
_actionSheet = [[UIActionSheet alloc] initWithTitle:#"Image Source" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Camera", #"Gallery", nil];
_actionSheet.tag = ACTION_IMAGE_SOURCE_TAG;
}
if (_isPad) {
[_actionSheet showFromRect:_imageButton.frame inView:_scrollViewContent animated:YES];
}else{
[_actionSheet showInView:self.view];
}
}
Delegate
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (actionSheet.tag) {
case ACTION_IMAGE_SOURCE_TAG:
switch (buttonIndex) {
case 0:
[self pickImage:YES];
break;
case 1:
[self pickImage:NO];
break;
default:
break;
}
break;
}
Executing
- (void)pickImage:(BOOL)fromCamera
{
if (fromCamera) {
if([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]){
UIImagePickerController* cameraPickerController = [[UIImagePickerController alloc] init];
cameraPickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
cameraPickerController.delegate = self;
[self presentViewController:cameraPickerController animated:YES completion:nil];
}else{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Camera Unavailable" message:#"Your Device does not support Cameras" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alert show];
}
}else{
UIImagePickerController *galleryPickerController = [[UIImagePickerController alloc] init];
galleryPickerController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
galleryPickerController.delegate = self;
if (_isPad) {
if ([_actionSheet isVisible]) {
[_actionSheet removeFromSuperview];
UIPopoverController *imagePickerPopover = [[UIPopoverController alloc] initWithContentViewController:galleryPickerController];
[imagePickerPopover presentPopoverFromRect:_imageButton.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
}else{
[self presentViewController:galleryPickerController animated:YES completion:nil];
}
}
}
Question: I tried removing the action sheet from view, and tried dismissing it before executing pickImage. None of that works. How do I present the gallery?
Your Problem: Error:Terminating app due to uncaught exception 'NSGenericException', reason: '-[UIPopoverController dealloc] reached while popover is still visible.
make Object of UIPopoverController in your .h file class. Make sure that your #property for your UIPopoverController is strong instead of weak.
Check this
UIPopoverController: dealloc reached while popover is still visible
UIPopovercontroller dealloc reached while popover is still visible
FYI, This was a comment and OP asked to put it as an answer. Because this solved the issue.
It's happening because you don't have a reference to your UIPopoverController. Have a strong reference for your imagePickerPopover and then try. No problem will occur.
you can try this:
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
if ([actionSheet isVisible]) {
[actionSheet dismissWithClickedButtonIndex:0 animated:NO];
}
}
}
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
UIImagePickerController *galleryPickerController = ......
}
}
I have an issue with my code, I have two blocks of code of UIAlertViews one with cancel and ok button, and the other to make a UIImagePicker
-(IBAction)publicaPeticion
{
if([txtPeticion hasText] )
{
UIAlertView *alerta = [[UIAlertView alloc]
initWithTitle:#"Confirmación de Compra"
message:#"Deseas comprar la petición por $12.00"
delegate:self
cancelButtonTitle:#"Cancelar"
otherButtonTitles:#"Aceptar", nil];
[alerta show];
}
}
The issue is between publicaPeticion and cargaImagen
-(IBAction)cargaImagen
{
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Subir una imagen"
message:#"¿De donde deseas subir una imagen?"
delegate:self
cancelButtonTitle:#"Cancelar"
otherButtonTitles:#"Desde el equipo",#"Tomar con camara", nil];
[alert show];
}
and also my method to get the source of the image, from the photo stream or from the camera
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex == 1)
{
picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:picker animated:YES];
}
if(buttonIndex ==2)
{
picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:picker animated:YES];
}
}
the question is, that when i press "Aceptar" button (OK), it takes me to the upload picture from the photo library...
maybe is a little bit silly the question but how can I differentiate it?
A couple ways.
1)
See how the delegate method is called?
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
From the alertView parameter, you can tell which alert did the calling (if you set cargaImagen and publicaPeticion's alertviews to separate instance variables).
2)
Another (and probably easier) thing you could do is to set a tag property on your alertView.
In your 'cargaImagen' method and right after you create the UIAlert, set the tag to 1 via alert.tag = 1;.
Then, in your alertView:clickedButtonAtIndex: delegate method, when alertView.tag == 1, you'll know it comes from cargaImagen and if it's 2 (or zero), you know it comes from publicaPeticion.