Why does UIActionSheet cancel crash my App? - iphone

I try to use the UIActionSheet within my iPhone App but have the following problem. When I tap the cancel button "I don't", the app crashes. When I remove the NSLog statement from the actionSheet:clickedButtonAtIndex: it does not. The "Yes, do it" button works just fine and I see the log statement in the console. What's wrong?
- (void) doItWithConfirm {
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#"do you really wanna do it?"
delegate:self cancelButtonTitle:#"I don't" destructiveButtonTitle: nil
otherButtonTitles:#"Yes, do it", nil];
[actionSheet showInView:self.view];
[actionSheet release];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
NSLog(#"buttonIndex: %#", buttonIndex);
}

NSLog(#"buttonIndex: %#", buttonIndex);
buttonIndex is an integer, and the %# only expects ObjC objects (not integers). This mismatch make the system crashes. Use
NSLog(#"buttonIndex: %d", buttonIndex);
instead.

Related

UIAlertViewDelegate not acting as expected

I have a very simple process running where after each round of a simple game the scores are calculated, labels updated and all the normal, very simple stuff. I have a UIAlertView that informs the player of how s/he performed. I use a UIAlertViewDelegate to postpone all the updates, resetting of controls etc. till after the UIAlertView is dismissed. The methods are [startNewRound],[startOver] and [updateLabels]. It's fairly obvious what they all do. Anyway, when the user hits round ten, I've made another UIAlertView that informs the player that the game has ended and shows the overall score. Again, I hoped to use a delegate to postpone the resets till after the AlertView is dismissed. The only problem is, with the endGame AlertView, it seems to be using the first AlertView's delegate method causing the game to continue with a new round and not start from the beginning. I hope this makes sense. Anyway, here are snippets of my code.
if (round == 10){
UIAlertView *endGame = [[UIAlertView alloc]
initWithTitle: #"End of Game"
message: endMessage
delegate:self
cancelButtonTitle:#"New Game"
otherButtonTitles:nil];
[endGame show];
}
else {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle: title
message: message
delegate:self
cancelButtonTitle:#"Next"
otherButtonTitles:nil];
[alertView show];
}
And then the delegate methods:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
[self startNewRound];
[self updateLabels];
}
- (void)endGame:(UIAlertView *)endGame didDismissWithButtonIndex:(NSInteger)buttonIndex
{
[self startOver];
}
So there it is. As I mentioned, the endGame AlertView appears to be using alertView's delegate, thus not activating the [self startOver] method. All the methods are working, it's just the AlertView is using the incorrect delegate method. Regards, Mike
Change your code like this,
if (round == 10){
UIAlertView *endGame = [[UIAlertView alloc]
initWithTitle: #"End of Game"
message: endMessage
delegate:self
cancelButtonTitle:#"New Game"
otherButtonTitles:nil];
endGame.tag = 111;
[endGame show];
}
else {
UIAlertView *alertView = [[UIAlertView alloc]
initWithTitle: title
message: message
delegate:self
cancelButtonTitle:#"Next"
otherButtonTitles:nil];
alertView.tag = 222;
[alertView show];
}
and delegate method as,
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if(alertView.tag == 111)
{
[self startNewRound];
[self updateLabels];
}
else if(alertView.tag == 222)
{
[self startOver];
}
}
You cant have two delegate method for dismisswithbuttonindex, you need to handle this situation with tag.
Give both alert view a different tag and check it on delegate object. Thus you can differentiat the both alert view.

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

UIAlertViewStylePlainTextInput - Program continues without waiting for text input from user

I'm sort of stuck on a UIAlertViewStylePlainTextInput. (My code is too long to post here, but this is the part where the problem exists.) It all sort of works, but the program doesn't wait until the user enters the information before continuing. The "editName" button doesn't change the display in the code below, but the updateDisplay button works fine (if you've pressed the "editName" button before you pressed "updateDisplay"). How can I get everything to sort of halt until the user enters the info (or cancels). Or is there some other lead that will take me where I need to go. (I've been toying with putting the rest of the code in the -(void) alertView, but that just doesn't seem to be the correct way of doing it).
Thanks in advance.
#import "HSTestViewController.h"
#implementation HSTestViewController
#synthesize display;
NSString *newName;
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 1)
{
newName = [[alertView textFieldAtIndex:0] text];
}
}
- (void) getNewName;
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"You made the High Score List"
message:#"Please enter your name"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok", nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
}
- (IBAction)editName:(id)sender
{
[self getNewName];
newName = display.text;
}
- (IBAction)updateDisplay:(id)sender
{
display.text = newName;
}
#end
Add UIAlertViewDelegate to the class. And implement the below delegate method.
OK button index value will be 1 in your case.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex)
{
// call the method or the stuff which you need to perform on click of "OK" button.
}
}
Hope this helps.

UIActionSheet, how to dismiss it with a single click?

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.