UIActionSheet, how to dismiss it with a single click? - iphone

UIActionSheet, how to dismiss it with a single click?
I have to click a button 2 times so it gets dismissed, what should I do to make it dismissble after the first click?! Here is my code:
-(void)buttonHeld:(id)sender
{
UIActionSheet *popupQuery = [[UIActionSheet alloc] initWithTitle:#"Delete Contact?!" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:#"Delete" otherButtonTitles: nil];
popupQuery.actionSheetStyle = UIActionSheetStyleBlackOpaque;
[popupQuery showInView:self.view];
[popupQuery release];
}
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) {
NSLog(#"Delete button clicked Button Clicked");
else if (buttonIndex == 1) {
NSLog(#"Cancel Button Clicked");
}
}

Based on the name of your method "buttonHeld", my assumption is that you are trying to launch the UIActionSheet from a UILongPressGestureRecognizer. You will need to use the code listed below if you want it to work as expected. The problem stems from UILongPressGestureRecognizer being a 'continuous gesture' which fires multiple times and progresses through several different states. You'll need to monitor for the correct state and then load your UIActionSheet. I had the exact same problem and this is what solved it for me.
- (IBAction) buttonHeld:(UILongPressGestureRecognizer *)sender {
if (sender.state == UIGestureRecognizerStateBegan) {
UIActionSheet *popupQuery = [[UIActionSheet alloc]
initWithTitle:#"Delete Contact?!"
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:#"Delete"
otherButtonTitles:nil];
popupQuery.actionSheetStyle = UIActionSheetStyleBlackOpaque;
[popupQuery showInView:self.view];
}
}

This is how i dismiss the actionsheet...
[actionSheet dismissWithClickedButtonIndex:0 animated:YES];
Hope this helps

It took me a few taps to get it to cancel as well. The problem ended up being which view I attached it to.
[action showInView:self.view];
self.view was only referenced in IB. I changed it to a different view and it worked.

No need to declare in this delegate when you alloc the actionsheet you have make cancel Button that by default dismiss the ActionSheet some thing like this
[[UIActionSheet alloc] initWithTitle:#"" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:btnTitle,#"Send for a date range",nil];
from any other event you can use this method
- (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated
In your code there is a syntax error you are putting else block in if block.

If u're developing for the iphone it's always safe to use :
[popupQuery showFromBarButtonItem:sender animated:YES]
or showFromTabBar: or showFromToolBar etc. instead of showinView.

Related

Don't Pop Navigation Controller in Xcode if AlertView

I have a Navigation Controller and when I press the back button I don't want to pop the view but I want to show an UIAlertView.I just want to pop the view after having make a choice on the UIAlertView!
How can I do?
I tried to catch the event 'back button pressed' but with no results :(
Create a UIBarButtonItem inside viewDidload and added it to the navigation bar
UIBarButtonItem *backButton=[[UIBarButtonItem alloc] initWithTitle:#"Back" style:UIBarButtonItemStyleBordered target:self action:#selector(backButtonClicked)];
self.navigationItem.leftBarButtonItem=backButton;
create a method which will be called when the backButton is clicked
-(void)backButtonClicked{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Pop View!" message:#"Are you sure?" delegate:self cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
[alert show];
}
write this UIAlertView delegate method which will be called when the button in the UIAlertView is clicked
-(void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex{
if (buttonIndex==1) {
[self.navigationController popViewControllerAnimated:YES];
}
}
NOTE: Dont forget to add UIAlertView delegate in the header file <UIAlertViewDelegate>
You can check for back-button press in the viewWillDisappear method like this (got it from here):
-(void)viewWillDisappear:(BOOL)animated {
if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound && self.isBackButtonPressed) {
// back button was pressed. We know this is true because self is no longer
// in the navigation stack.
}
[super viewWillDisappear:animated];
Hope this helps!
Implement pop in UIAlertview delegate method clickedButtonAtIndex:
The back button press need to implement only showing the UIAlertview
refer this
follow this code
in button action.
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message" message:#"Do you want to open?" delegate:self cancelButtonTitle:#"NO" otherButtonTitles:#"YES", nil];
[alert show];
//Alert View delegate method
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if(buttonIndex==0)//NO
{
//your code
}
else if(buttonIndex==1)//YES
{
// your code
}
}

Multiple alertviews in a single view?

I have an Iphone application in which when i am pressing a button it shows an alertview to chose the background.whichever background user is chosing will be played as the background of the audio clips.But now i need to add another alert before i am showing this alert for giving some warning.after that only i need to pop the second one.but i was done that chosing alert in the didappear of that viewcontroller and set it as a Uialertview delegate.and on the button actions i was doing different actions.Can anybody help me on achieving this?
proAlertView *loginav1=[[proAlertView alloc] initWithTitle:#"title" message:#"Choose a Background to play with this program?" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Field",#"Beach", #"Stars",nil];
[loginav1 setBackgroundColor:[UIColor colorWithRed:0.129 green:0.129 blue:0.129 alpha:1.0] withStrokeColor:[UIColor colorWithHue:0.625 saturation:0.0 brightness:0.8 alpha:0.8]];
[loginav1 show];
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
// the user clicked one of the OK/Cancel buttons
if (buttonIndex == 0)
{
//[self play];
//moviePlayer.scalingMode=MPMovieScalingModeAspectFill;
if(actionSheet.tag==123)
{
[self backButtonPressed];
}
}
else if (buttonIndex == 1)
{
videoFile = [[NSBundle mainBundle] pathForResource:#"video-track" ofType:#"mp4"];
[self play];
moviePlayer.scalingMode=MPMovieScalingModeAspectFill;
}
how can i include another alert before this is my question?
Initialize first Alertview
UIAlertView *al1 = [[UIAlertView alloc] initWithTitle:#"Warning!" message:#"Warning Msg!!!" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles: nil];
al1.tag=1;
al1.delegate=self;
[al1 show];
Implement Delegate method
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
if(alertView.tag==1){
// implement button events for first Alertview
if(buttonIndex==1){
//First button clicked of first Alertview
UIAlertView *al2 = [[UIAlertView alloc] initWithTitle:#"Choose BG" message:#"Choose BG?" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"1",#"2",#"3", nil];
al2.tag=2;
al2.delegate=self;
[al2 show];
}
}
if(alertView.tag==2){
// implement button events for second Alertview
if(buttonIndex==1){
// First button clicked second Alertview.
}
}
}
Controller Class header
#interface ViewController : UIViewController<UIAlertViewDelegate>{
}
Hope this will fulfill your need !
You can do like this, first display warning message in alertview and when user click OK in alertview then in alertview delegate method write code to display second alertview where user can choose background.

Can not dismiss an action sheet here

A UILongPressGestureRecognizer is added to my imageView with action handleLongPressOnPhotos. The most related codes is as following:
- (IBAction)handleLongPressOnPhotos:(UILongPressGestureRecognizer *)sender
{
self.imageWillBeSaved = (UIImageView *)sender.view; //breakPoint1
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:#"Save the photo" otherButtonTitles: #"Go to the Original photo", nil];
actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
[actionSheet showInView:self.view]; //breakPoint2
NSLog( #"actionSheet addr when created is %p", actionSheet );//breakPoint3
[actionSheet release];//breakPoint4
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch (buttonIndex) {
case 0:
UIImageWriteToSavedPhotosAlbum(self.imageWillBeSaved.image, self, #selector(image: didFinishSavingWithError:contextInfo:), nil);
//[actionSheet dismissWithClickedButtonIndex:0 animated:YES]; i have tried to use this method here, but it didn't work.
break;
default:
break;
}
}
- (void)image:(UIImage *)image didFinishSavingWithError:(NSError *)error contextInfo:(void *)contextInfo
{
if (error != NULL)
{
// handle error
}
else
{
// handle ok status
}
}
The action sheet will not be dismissed after i click the "save the photo" button. If i click the button again, the action sheet dismissed and the photo saved twice.Any problem in the code? Thanks in advance!
Ps. the imageView is a subview of a scrollView, and the scrollView is in a tableViewCell.
- (IBAction)handleLongPressOnPhotos:(UILongPressGestureRecognizer *)sender
{
self.imageWillBeSaved = (UIImageView *)sender.view; //breakPoint1
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:#"Save the photo" otherButtonTitles: #"Go to the Original photo", nil];
actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
[actionSheet showInView:self.view]; //breakPoint2
NSLog( #"actionSheet addr when created is %p", actionSheet );//breakPoint3
[actionSheet release];//breakPoint4
}
I set two breakpoint in the "handleLongPressOnPhotos:" method as breakPoint1 and breakPoint1. I followed the steps of the code after the imageView was longPressed. The step order is :breakPoint1 -> breakPoint2 ->breakPoint1 ->breakPoint2 - > breakPoint3 -> breakPoint4 - > breakPoint3 -> breakPoint4, then went out. It is obvious that the actionSheet has been presented twice, that cause the problem. It is odd, and I do not know the reason and avoid this.
Problem solved in another question UILongPressGestureRecognizer gets called twice when pressing down
thanks to #Laddu, #MichaelDautermann, #sreecharan
IT Looks OK but please add nslog here:-
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex{
NSLog(#"buttonIndex.....%d",buttonIndex);
switch (buttonIndex) {
case 0:
UIImageWriteToSavedPhotosAlbum(self.imageWillBeSaved.image, self, #selector(image: didFinishSavingWithError:contextInfo:), nil);
//[actionSheet dismissWithClickedButtonIndex:0 animated:YES]; i have tried to use this method here, but it didn't work.
break;
default:
break;
}
}
Check you add ACtionSheet Delegate in .h file also .
is there a reason why you are not using actionSheet:willDismissWithButtonIndex: instead of actionSheet:clickedButtonAtIndex:.
If you use actionSheet:willDismissWithButtonIndex:, you don't need to care about dismissing the ActionSheet yourself.
Problem solved in another question UILongPressGestureRecognizer gets called twice when pressing down
thanks to #Laddu, #MichaelDautermann, #sreecharan

How to show an AlertView with another AlertView

I want to show nested alertViews. Problem, which i am facing in nested alertViews is that when i click an "add" button of first alertView it shows the second alertView, in second alertView i have a textField and a "Save" button. I want to save data when i click on save button and then reload UITableViewData, which is already in the first alertView.
I am new in iphone, so please help me.
You should create your alert views with different tag property so that in delegate method you can easily differentiate which alert view is appeared on the screen.
For example :
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:#"Info"
message:#"Message" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil] autorelease];
[alert setTag: 1001]; // give different tag to different alert views
[alert show];
[alert release];
Now in delegate method :
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView.tag == 1001)
{
// do something
}
eles if (alertView.tag == 1002)
{
}
}
Hope it helps you..

UIActionSheet Customization

Can you control the size of the text and it's alignment on the action sheet? Also, Can you decide the order in which the destructivebutton and otherbuttons will appear on the action sheet? The screenshot like screen is what I am trying to create.
Thanks in advance
I did something like this to customize an Action Sheet:
-(void) showPopup {
unitPicker *pc = [[unitPicker alloc] init];
UIActionSheet *popupQuery = [[UIActionSheet alloc]
initWithTitle:#"Units"
delegate:pc
cancelButtonTitle:nil
destructiveButtonTitle:nil
otherButtonTitles:nil
];
[pc setParent:self];
popupQuery.actionSheetStyle = UIActionSheetStyleBlackOpaque;
[popupQuery showInView:self.view];
[popupQuery setBounds:CGRectMake(0,0,320, 350)];
[pc setAs:popupQuery];
[popupQuery addSubview:pc.view];
}
The trick being that "unitPicker" was derived from a UIControllerView, but implemented the UIActionSheetDelegate protocol. It supplied the two functions:
- (void)actionSheet:(UIActionSheet *)actionSheet willDismissWithButtonIndex:(NSInteger)buttonIndex;
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex;
To deal with any cleanup. The big part was that the format of unitPicker was created from a NIB, as it would with any UIViewController.
The buttons in the view dismissed the actionSheet with the code in their touchUpInside handlers:
[as dismissWithClickedButtonIndex:0 animated:TRUE];
(You can see in the code above that "as" was set to be the actionSheet object).