In my iPhone app, I have a NSObjectA class and a UIViewController B class. I want to call a instance method in B class from A. I used the following code.
Bclass *vc = [[Bclass alloc]init];
[vc hideAlert:NSString];
[vc release];
and in B class:
- (void)hideAlert:(NSString*)message{
UIAlertView *shareAlrt = [[UIAlertView alloc] initWithTitle:#""
message:message
delegate:self
cancelButtonTitle:#"Ok"
otherButtonTitles:nil];
[shareAlrt show];
[shareAlrt release];
}
and the method called and show a AlertView. When click on the Ok button, I want to navigate to class Cclass.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
Cclass *vc = [[Cclass alloc]initWithNibName:#"Cclass" bundle:[NSBundle mainBundle]];
[self presentModalViewController:vc animated:NO];
[vc release];
}
}
But when I click on the Ok button, the app crashes. Whats happening here? I have added <UIAlertViewDelegate> in the B class.h file, but still the same error. Please help
I am getting the error code *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType alertView:clickedButtonAtIndex:]: unrecognized selector sent to instance 0x81baa80'
Just change the method
- (void)hideAlert:(NSString*)message{
UIAlertView *shareAlrt = [[UIAlertView alloc] initWithTitle:#""
message:message
delegate:self
cancelButtonTitle:nil
otherButtonTitles:#"Ok",nil];
[shareAlrt show];
[shareAlrt release];
}
This has been answered by presuming that u have no other button except cancel button titled as "OK". Assumption is made by seeing your displayed code.
You have used Cancel button on which u cant handle delegate to perform any action.
If you look at the documentation of UIAlertViewDelegate class reference
Optionally, you can implement the alertViewCancel: method to take the
appropriate action when the system cancels your alert view. If the
delegate does not implement this method, the default behavior is to
simulate the user clicking the cancel button and closing the view.
Related
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.
I create a class to call UIAlertview show on my screen. I write the UIAlert function in another class. Both these two classes are not my viewController class.
I use this UIAlert, which is a UITextfield inside, to store texts into a plist file.
here is the class to call UIAlert:
#import "Story.h"
#implementation Story
...
+ (void)stage1
{
AlertClass *pointer = [AlertClass new];
[pointer doAlert];
}
here is the class AlertClass.m file:
- (void)doAlert
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Title" message:#"Message" delegate:self cancelButtonTitle:#"Done" otherButtonTitles:nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
[alert show];
}
//this makes crash!
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
self.storyFlow.text = [alertView textFieldAtIndex:0].text;
}
Before I add UIAlertViewDelegate in the .h and override the method "clickedButtonAtIndex", it works great. However, I need to store some data from the UITextfield inside the alert view. I get crash and don't know the message it responds as following.
Please help me to solve this problem. Thanks.
[crash pic] https://dl.dropbox.com/u/47381923/crash.tiff
do an NSLog on the text you get back from the Alert View to see whether that is the crash or the subsequent 'self.storyFlow.text = ' is causing it. Perhaps self.storyFlow has not been created yet (with alloc/init)
I have this code:
//SHOW ALERT
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Actualizado"
message:#"Se ha actualizado todo" delegate:self
cancelButtonTitle:#"Aceptar" otherButtonTitles:nil, nil];
[alert show];
and this
- (void)alertView:(UIAlertView *)alert
clickedButtonAtIndex:(NSInteger)buttonIndex {
NSLog(#"ALgo"); }
and got the following error:
-[__NSCFType alertView:clickedButtonAtIndex:]:
unrecognized selector sent to instance 0xdc559a0
Help please.
Thanks
Looks like you might be releasing the object or view that handles the alertView:clickedButtonAtIndex: selector (the delegate). Make sure you keep it until your UIAlertView has been dealt with.
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Actualizado" message:#"Se ha actualizado todo" delegate:self cancelButtonTitle:#"Aceptar" otherButtonTitles:nil, nil];
try this
have you added the UIAlertViewDelegate to your header file?
e.g
#interface yourclass: UIViewController
check if this may be the reason
If your alertView is created inside a object instantiated from a ViewController, you need to keep a pointer to that object in the ViewController.
would you please look at that piece of code:
/* This app is a game, the user can click an "abort" button anytime,
* and he/she is therefore asked for confirmation ("really abort game?")
*/
- (IBAction)btnAbortClicked:(id)sender {
UIAlertView *alert = [[UIAlertView alloc] init];
[alert setMessage:#"Really abort game?"];
[alert setDelegate:self];
[alert addButtonWithTitle:#"Yes"];
[alert addButtonWithTitle:#"No"];
[alert show];
[alert release];
}
/* Delegate method (I don't like it, I wish I had modal blocking windows) */
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0)
[self quitGame];
}
/* pop the view controller */
- (void)quitGame {
[self.navigationController popToRootViewControllerAnimated:YES];
}
The problem is simple - but apparently not enough for me to solve. The UIViewController gets popped, but doesn't get deallocated. And the problem is strictly related to the UIAlertView, because if I just call quitGame from btnAbortClicked:, the view controller is popped and immediately deallocated.
Instead, it seems some mysterious entity retains it.
Can you help me? Thanks in advance.
Well, I think that you're still inside the alertView when clickedButtonAtIndex is called. I'd suggest moving to alertView:disDismissWithButtonIndex instead, so that you're called after the alertview disappears.
I'm having a similar issue to Anthony Chan's question, and after trying every suggested solution, I'm still stuck.
Somehow, only after interacting with my UIAlertView, I'm unable to dismiss the keyboard in another view of my app. It's as though the Alert is breaking my UITextField's ability to resignFirstResponder. Below I instantiate my UIAlertView, which then calls its didDismissWIthButtonIndex method. Then, I call the showInfo method, which loads another UIViewController.
UIAlertView *emailFailAlert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"error message text."
delegate:self
cancelButtonTitle:#"Not now"
otherButtonTitles:#"Settings", nil];
[emailFailAlert setTag:2];
[emailFailAlert show];
[emailFailAlert release];
Once the 'Settings' option is pressed, I'm calling this method:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if ([alertView tag] == 2) {
if (buttonIndex == 1){
[self showInfo:nil];
}
}
}
My showInfo method loads the other ViewController, via the code below:
- (IBAction)showInfo:(id)sender {
FlipsideViewController *fscontroller = [[FlipsideViewController alloc] initWithNibName:#"FlipsideView" bundle:nil];
fscontroller.delegate = self;
fscontroller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:fscontroller animated:YES];
[fscontroller release];
}
Upon clicking any textField in this Flipside VC, I'm unable to dismiss the keyboard as I normally can with - (BOOL)textFieldShouldReturn:(UITextField *)textField, and [textField resignFirstResponder]. I've omitted this code bc this question is getting long, but I'm happy to post if necessary.
The interesting part is that if I comment out the [self showInfo:nil] call made when the button is clicked and call it by clicking a test button (outside the alertView didDismissWithButtonIndex: method), everything works fine. Any idea what's happening here?
Thanks in advance!
When an alert, with more than one dismissal option, is called above a keyboard - the keyboard becomes un-dismissible with resignFirstResponder on the active textfield;
You will need to dismiss the keyboard before showing the alert.
Assuming your UITextField is called myTextField;
[myTextField resignFirstResponder]; //That's the only line I added
UIAlertView *emailFailAlert = [[UIAlertView alloc] initWithTitle:#"Error"
message:#"error message text."
delegate:self
cancelButtonTitle:#"Not now"
otherButtonTitles:#"Settings", nil];
[emailFailAlert setTag:2];
[emailFailAlert show];
[emailFailAlert release];
I hope this helps anyone who had to deal with this oddly obscure issue.
You should not call alertView:didDismissWithButtonIndex: directly. This delegate method will be executed automatically in all cases after the alert has disappeared. Otherwise the code will be run twice!