I have a class as follows
#import "UtilAlert.h"
#implementation UtilAlert
+(void) showAlert:(NSString *)message andTitle:(NSString *)title andDelegate:(UIViewController *) delegate
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:delegate cancelButtonTitle:#"Cancel" otherButtonTitles:nil];
[alert show];
}
#end
The problem is that when call the function with necessary parameters...
[UtilAlert showAlert:#"hello" andTitle:#"hello" andDelegate:self] ;
i get a error: Thread 1: stopped at break point 3;
for the function call from an UIController class
This is not an error. You have a breakpoint in your code, which is the little blue arrow in the left margin of your code. Click the blue arrow again to make it really light blue to turn off the breakpoint.
Also, you should release the alert after showing it before exiting the function or you will leak memory.
Just a wild guess, but your alert object may be released when the function exits if your are working on ARC. In that case, this might work :
+(void) showAlert:(NSString *)message andTitle:(NSString *)title andDelegate:(UIViewController *) delegate {
static UIAlertView *alert;
if(!alert)
alert = [[UIAlertView alloc] initWithTitle:title message:message delegate:delegate cancelButtonTitle:#"Cancel" otherButtonTitles:nil];
[alert show];
}
Related
I am a newbie in objective c;
I am getting an error at creating a UIAlertview instantiation statements (UIAlert * myAlert, they are in separate scopes)
I have referred the following stackoverflow entries such as This, this, this too and much more research over the internet.
I am unable to get a break through
Following are my alert calls
This is my view controller code where I have put up the "UIAlertViewDelegate"
#import <UIKit/UIKit.h>
#interface gameFirstViewController : UIViewController<UIAlertViewDelegate>
#end
This is my class declaration
#import <Foundation/Foundation.h>
#interface GameLogic : UIView
//all sorts of various non relevant property declarations
#end
Here is my implementation for the alerts
//action to take when an alert is shown
- (void)alertView:(UIAlertView *)alertView
didDismissWithButtonIndex:(NSInteger) buttonIndex
{ NSLog(#"OK Tapped");
NSUserDefaults *MySettingsData = [NSUserDefaults standardUserDefaults];
row= [MySettingsData integerForKey:#"Row_count"];
col = [MySettingsData integerForKey:#"Column_count"];
if(buttonIndex==0)
{
for(int i=0;i<row;++i)
{
for(int j=0;j<col;++j)
{
myarr[i][j]=0;
}
}
if(_TimerStatus ==1)
{
[mainTimer invalidate];
mainTimer=nil;
_TimerStatus=0;
}
[self super_reset];
[self setNeedsDisplay];
NSLog(#"Game reset");
return;
}
}
//my usage of the alerts at 2 different places
UIAlertView *myAlert = [[UIAlertView alloc]initWithTitle: #"GAME OVER"
message:#"You clicked on a mine, tap on ok to reset"
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil, nil];
[myAlert performSelectorOnMainThread:#selector(show)
withObject:nil
waitUntilDone:YES];
UIAlertView *myAlert = [[UIAlertView alloc]initWithTitle: #"You Won! Whoo Hoo"
message:#"You have successfully dodged every minefield"
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil, nil];
[myAlert performSelectorOnMainThread:#selector(show)
withObject:nil
waitUntilDone:YES];
I am not sure where I am going wrong, any help would be great!
Thanks.
The way you are creating the UIAlertView is not safe in ARC. It's fine if you use the object right away, but you're passing it the performSelectorOnMainThread method. ARC may dealloc your myAlert variable by the time the main thread gets to perform the selector. That's likely why you're seeing the EXC_Bad_Request.
Either make myAlert a strong property, so it survives, or delay the creation of the UIAlert until the main thread is able to call the show method. You can do that like this:
dispatch_async(dispatch_get_main_queue(), ^{
[[[UIAlertView alloc] initWithTitle:#"GAME OVER" message:#"You clicked on a mine, tap on ok to reset" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil] show];
});
Note: I removed your double nil for the titles. I don't think that would make a difference, but just in case.
I need help on dismissing a UIAlertView programmatically. Currently I have this
UIAlertView *alert1 = [[UIAlertView alloc]initWithTitle:#"title" message:#"message" delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
then later on I call this
[alert1 dismissWithClickedButtonIndex:0 animated:NO];
but nothing happens.
You need to set two things.
1. include your .h file : <UIAlertViewDelegate>
2. please follow below implementation...
UIAlertView *alert1 = [[UIAlertView alloc]initWithTitle:#"title" message:#"message" delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
[alert1 show];
[self performSelector:#selector(dismiss:) withObject:alert1 afterDelay:1.0];
the dismiss method will be...
-(void)dismiss:(UIAlertView*)alert
{
[alert dismissWithClickedButtonIndex:0 animated:YES];
}
I hope this will help you.
I encountered this problem too.
In my case, for some reason calling:
[alert dismissWithClickedButtonIndex:0 animated:NO];
didn't work always (yes, even calling it on UI thread and yes, alert != nil), instead simply setting the animated flag to YES it worked:
[alert dismissWithClickedButtonIndex:0 animated:YES];
Maybe it's an Apple bug...
you should display it first:
UIAlertView *alert1 = [[UIAlertView alloc]initWithTitle:#"title" message:#"message" delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:nil];
[alert1 show];
then in delegate method
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex{
if(buttonIndex==0){
// do something
}
}
The methods you called is correct.
I guess the alert1 is nil when your call the method dismissWithClickedButtonIndex:animated:
Try to check your variable alert1.
You can use the delegate method -alertView:didDismissWithButtonIndex: instead—it gets called once the alert view’s been removed from the screen, OR better approach is , use a background thread, e.g. with -performSelectorInBackground:withObject:, to handle whatever processing you need to do.
in my Alert View, there is two button, OK and Cancel. When the user click the OK button, the delegate method dismissWithClickedButtonIndex:animated get called, and if the index is 0, then i get called to a method to execute some code:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Alert"
message:#"Are you sure you want to exit"
delegate:self cancelButtonTitle: #"OK"
otherButtonTitles: #"Cancel",nil];
[alert show];
[alert release];//release the reference
Delegate method:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex{
if (buttonIndex==0) {
[self aMethod];
}
}
-(void)aMethod{
//Some useful code
}
Now, what i want to instead of all this, is to execute the code of the aMethod method in the AlertView directly, without referring to A delegate method and a method which get called, something like that:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Alert"
message:#"Are you sure you want to exit"
delegate:self cancelButtonTitle: #"OK" //Put here some useful code
otherButtonTitles: #"Cancel",nil];
Is it possible?
Unfortunately this is not possible at this time (iOS 5.1). The AlertView class does not support blocks.
I made a pair of UIAlertView and UIActionSheet subclasses that do exactly that. Grab them here:
https://github.com/rydermackay/RMActionSheet
Use them like this:
RMAlertView *alertView = [RMAlertView alertViewWithTitle:#"Alert!" message:nil];
[alertView addButtonWithTitle:#"OK"
action:^{
NSLog(#"OK");
}];
[alertView addCancelButtonWithTitle:#"Cancel"
action:nil];
[alertView show];
EDIT:
From your comments it sounds like you're not familiar with blocks. Read this now. Seriously.
http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/00_Introduction.html
This is a good one too:
http://www.mikeash.com/pyblog/friday-qa-2009-08-14-practical-blocks.html
In my application I have implemented the Push notification feature and I am getting the notifications. I used the following code in the appDelegate file.
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
for (id key in userInfo) {
NSMutableArray *array = [userInfo objectForKey:key];
NSString *message = [NSString stringWithFormat:#"%#",[array valueForKey:#"alert"]];
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"iPhoneApp" message:message delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
[alert show];
[alert release];
}
}
I want to perform actions on the OK button click event of the Push notification alert (when the app is running). I have three view controllers in this app. So in which class should I add the code
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex?
In the same class you set as the delegate of that particular UIAlertView. In your current case, the AppDelegate is the receiver of the -clickedButtonAtIndex:.
If you would like to receive the click events in one of the 3 controllers you have. You must set that particular controller as the delegate to your UIAlertView:
UIAlertView *alert = [[UIAlertView alloc]initWithTitle:#"iPhoneApp" message:message delegate:myViewController cancelButtonTitle:#"Cancel" otherButtonTitles:#"Ok", nil];
[alert show];
[alert release];
As you see I assigned myViewController as the delegate. myViewController should conform to the UIAlertViewDelegate protocol and implement the -clickedButtonAtIndex: method. Now once you select one of the button's you will get the call in myViewController.
I am calling UIAlert with 2 buttons "Cancel" and "OK" in MyapplicationAppDelegate.m file , the alert is called but on tap of "Cancel" or "OK" button
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
method is not called.
I have added UIAlertViewDelegate in the MyapplicationAppDelegate.h file as below
#import UIKit/UIKit.h
#interface MyapplicationAppDelegate: NSObject UIApplicationDelegate,UIAlertViewDelegate
{
..
}
I want to know what else is required.
I am not sure whether its your typo while posting the question but you should call the delegate within <.. , .. >
#interface MyapplicationAppDelegate: NSObject <UIApplicationDelegate,UIAlertViewDelegate> { .. }
Here is sample code for UIAlertView
UIAlertView *myAlertView = [[UIAlertView alloc]initWithTitle:#""message:#"Your message goes here" delegate:self cancelButtonTitle:#"OK"otherButtonTitles:nil];
[myAlertView show];
[myAlertView release];
I am not sure myAlertView.delgate = self is the right method but i do set delegate with initWithTitle
For me,
#define appDelegate ((AppDelegate*)[UIApplication sharedApplication].delegate)
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil
message:#"Say Yes or NO?" delegate:appDelegate
cancelButtonTitle:#"No" otherButtonTitles:#"Yes", nil];
alertView.tag = 1;
[alertView show];
[alertView release];
do the trick!
Now its going into, -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex; in AppDelegate file without adding,
#interface MyapplicationAppDelegate: NSObject <UIApplicationDelegate,UIAlertViewDelegate> { .. }