Open an UIAlertView again from its own delegate fails in iOS - objective-c

I have an iPhone App that opens an UIAlertView with an UITextInput field and a button. When the button gets pressed the delegate method should do a validation of the input and on success proceed app execution or open the same UIAlertView again on failure.
Now I reduced it to this litte test class with two UIAlertViews. It is always possible to open the other view but when I hit the button it asks for the screen remains empty.
#import "Yesorno.h"
#implementation Yesorno
#synthesize promptYES, promptNO;
- (id)init {
self = [super init];
if (self) {
promptYES = [[UIAlertView alloc] init];
[promptYES setDelegate:self];
[promptYES setTitle:#"Press YES"];
[promptYES addButtonWithTitle:#"YES"];
[promptYES addButtonWithTitle:#"NO"];
promptNO = [[UIAlertView alloc] init];
[promptNO setDelegate:self];
[promptNO setTitle:#"Press NO!"];
[promptNO addButtonWithTitle:#"YES"];
[promptNO addButtonWithTitle:#"NO"];
}
return self;
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0)
[promptYES show];
else
[promptNO show];
}
#end
Edit: here is the AppDelegate. It is now really a very basic application without any view controller
#import "AppDelegate.h"
#import "Yesorno.h"
#implementation AppDelegate
#synthesize window, yesorno;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window makeKeyAndVisible];
yesorno = [[Yesorno alloc] init];
[yesorno.promptYES show];
return YES;
}
#end
Any ideas how I could show the same dialog again? Thanks.

You should implement didDismissWithButtonIndex delegate method:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0)
[promptYES show];
else
[promptNO show];
}

You need to reimplement your - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex: delegate method.
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if(alertView == promptYES)
{
if (buttonIndex == 0)
[promptYES show];
}
else if(alertView == promptNO)
{
if (buttonIndex == 0)
[promptNO show];
}
}

Related

What's a simple way to get a text input popup dialog box with Actionsheet picker on an iPhone

want to get input from pickerView in textField when alert show Objective C
NOTE: Opening actionsheet from alertview first dismiss your alertview then open actionsheet.My code may help you regarding opening actionsheet from alertview
#import "ViewController.h"
#interface ViewController ()<UITextFieldDelegate,UIActionSheetDelegate>
{
NSString *alertSelectValue;
UITextField * alertTextField;
}
#end
#implementation ViewController
- (void)viewDidLoad {
UIAlertView * alert = [[UIAlertView alloc] initWithTitle:#"Hello!" message:#"Please enter your name:" delegate:self cancelButtonTitle:#"Continue" otherButtonTitles:nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
UITextField * alertTextField = [alert textFieldAtIndex:0];
alertTextField.tag=101;
alertTextField.delegate=self;
alertTextField.keyboardType = UIKeyboardTypeNumberPad; alertTextField.placeholder = #"Enter your name";
[alert show];
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)textFieldDidEndEditing:(UITextField *)textField
{
if (textField.tag==101)
{
[textField setUserInteractionEnabled:YES];
[textField resignFirstResponder];
NSString*String = [NSString stringWithFormat:#"%#",textField.text];
[self openSheet:String];
}
}
-(void)openSheet:(NSString*)text
{
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#"Select" delegate:self cancelButtonTitle:#"OK" destructiveButtonTitle:nil otherButtonTitles:text,#"Test" ,nil];
actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
UIViewController *topvc=[self topMostController];
[actionSheet showInView:topvc.view];
}
//-------- Get top Most view to -----
- (UIViewController*) topMostController
{
UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
while (topController.presentedViewController) {
topController = topController.presentedViewController;
}
return topController;
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSLog(#"Index = %d - Title = %#", buttonIndex, [actionSheet buttonTitleAtIndex:buttonIndex]);
if(buttonIndex == 0)
{
alertTextField.text= [actionSheet buttonTitleAtIndex:buttonIndex];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end

Objective C UIAlertView queue

I want to show multiple messages on iOS one by one, but the problem is that showing UIAlertView is non-blocking. I tried to handle alert closing with clickedButtonAtIndex and show same alert inside. Here is some code:
#interface ViewController : UIViewController <UIAlertViewDelegate>
...
#property UIAlertView *alert;
...
#end
...
[alert show]; //somewhere in code, starts chain of messages
...
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
// Some changes in alert object
[alert show];
}
I would have one UIAlertView and change its message on button click... Maybe increment its tag as well
try overriding
-(void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
instead of clickedButtonAtIndex
I prefer to set tags on the alert views:
#define ALERT_1 1
#define ALERT_2 2
...
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:...];
alert.tag = ALERT_1;
[alert show]; //somewhere in code, starts chain of messages
...
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
switch (alertView.tag) {
case ALERT_1: {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:...];
alert.tag = ALERT_2;
[alert show];
} break;
case ALERT_2: {
....
} break;
}
}
This way you don't have to use variables for the alert views.
You need one property for each alert view you want to show. In the delegate function check which one finished and start the next one:
#interface ViewController : UIViewController <UIAlertViewDelegate>
...
#property UIAlertView *alert1;
#property UIAlertView *alert2;
#property UIAlertView *alert3;
#end
...
alert1 = [[UIAlertView alloc] initWithTitle:...];
[alert1 show]; //somewhere in code, starts chain of messages
...
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (alertView == alert1) {
alert2 = [[UIAlertView alloc] initWithTitle:...];
[alert2 show];
} else if (alertView == alert2) {
alert3 = [[UIAlertView alloc] initWithTitle:...];
[alert3 show];
}
}

Alert View button actions not working

I am using an Alert view to bring up a popup where the user will choose to either select a photo from the library or take a photo to use. The alert view comes up fine, but when I select a button the code I have implemented is not run?!?
for some reason the - (void)picturePopup:(UIAlertView *)picturePopup clickedButtonAtIndex:(NSInteger)buttonIndex does not seem to even get run!? I'm lost run over lots of tutorials and websites but can't see why?! please help!
code:
.m
#import "LoadViewController.h"
#implementation LoadViewController
int imageCase;
- (IBAction)pick:(id) sender {
imageCase = [sender tag];
UIAlertView *picturePopup = [[UIAlertView alloc]
initWithTitle:#"Select Photo" message:nil delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Choose From Library", #"Take Photo", nil];
[picturePopup show];
}
- (void)picturePopup:(UIAlertView *)picturePopup clickedButtonAtIndex:(NSInteger)buttonIndex {
NSLog(#"***************getting here****************");
if (buttonIndex == 1) {
NSLog(#"***************library****************");
//Library Picker
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
[self presentModalViewController:picker animated:YES];
}
if (buttonIndex == 2) {
NSLog(#"***************camera****************");
//Camera
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
[self presentModalViewController:picker animated:YES];
}
}
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingImage:(UIImage *)image editingInfo:(NSDictionary *)editingInfo {
switch (imageCase) {
case 1:
imageView1.image = image;
break;
case 2:
imageView2.image = image;
break;
}
[picker.parentViewController dismissModalViewControllerAnimated:YES];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[picker.parentViewController dismissModalViewControllerAnimated:YES];
}
#end
.h
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#interface LoadViewController : UIViewController <UINavigationControllerDelegate, UIImagePickerControllerDelegate, UIAlertViewDelegate> {
IBOutlet UIImageView *imageView1;
IBOutlet UIImageView *imageView2;
}
- (IBAction)pick:(id) sender;
#end
You need to use the actual delegate method:
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
This is not the same as:
- (void)picturePopup:(UIAlertView *)picturePopup clickedButtonAtIndex:(NSInteger)buttonIndex
The method signatures are different. alertView:clickedButtonAtIndex: vs. picturePopup:clickedButtonAtIndex:
You can rename the variable you just can not change the method signature.
This is sort of off topic, but I notice you didn't synthesize *imageView1 and *imageView2. lol

Using addSubView or presentModalViewController in a standard method with paramaters?

I'm trying to reuse code, I have some tutorial view controllers / views, which I would like to call from an action sheet. However, the calling views are different. Sometimes the tutorial view(s) would need to be added as a subview and sometimes they would be added to the navigation controller.
How can I expand my standard function to cater for these two different situations ?
You can see what I'm having to do instead, which means duplicate code :(
I have a class called which holds the standard code, I want to add calls to views here directly.
-(void)showHelpClickButtonAtIndex:(int)buttonIndex:(UIView *)vw {
if (buttonIndex == CommonUIHelpPagesBtnIdx) {
// do nothing
} else if (buttonIndex == 0) {
NSLog(#"Tutorial here");
}
}
I use in one view like this ...
- (void)actionSheet:(UIActionSheet *)actionSheet
clickedButtonAtIndex:(NSInteger)buttonIndex {
CommonUI *cui = [CommonUI alloc];
[cui showHelpClickButtonAtIndex:buttonIndex:self.view];
[cui release];
if (buttonIndex == CommonUIHelpPagesBtnIdx) {
UIViewController *theController = [[HelpViewController alloc]
initWithNibName:#"HelpView"
bundle:nil onPage:HelpPageCalcBalance];
[self.navigationController.topViewController
presentModalViewController:theController animated:YES];
[theController release];
}
}
And is another view like this...
- (void)actionSheet:(UIActionSheet *)actionSheet
clickedButtonAtIndex:(NSInteger)buttonIndex {
[cui showHelpClickButtonAtIndex:buttonIndex:self.view];
if (buttonIndex == CommonUIHelpPagesBtnIdx) {
theController = [[HelpViewController alloc] initWithNibName:#"HelpView"
bundle:nil onPage:HelpPageGettingStarted];
[self.view addSubview:theController.view];
}
}
Maybe the actionSheets could share one same delegate that would be a root viewController or the appDelegate that would know what to do according to it's current state. Hence the same actionSheet method would be used in both case.
If you put your appDelegate which can always be reached as the actionSheetDelegate, you should be able to gain control on every way to present your view, either modally or not in any of your views + the window.
EDIT (re-Edited with your code): Maybe try this
MyAppDelegate.h:
#interface MyAppAppDelegate : NSObject <UIApplicationDelegate, UIActionSheetDelegate>
(...)
- (void) showHelp;
MyAppDelegate.m:
- (void) showHelp {
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#""
delegate:self
cancelButtonTitle:#"Cancel"
destructiveButtonTitle:nil
otherButtonTitles: #"Tutorial", #"Help Pages", nil];
actionSheet.actionSheetStyle = UIActionSheetStyleBlackOpaque;
[actionSheet showInView:window];
[actionSheet release];
}
- (void)actionSheet:(UIActionSheet *)actionSheet
clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == CommonUIHelpPagesBtnIdx) {
UIViewController *theController = [HelpViewController alloc];
if ([[self lvc] superview] != nil) {
theController = [initWithNibName:#"HelpView"
bundle:nil
onPage:HelpPageGettingStarted];
[window addSubview:theController.view];
} else {
theController = [initWithNibName:#"HelpView"
bundle:nil
onPage:HelpPageCalcBalance];
UINavigationController * navController = [tabBarController selectedViewController];
[navController.topViewController presentModalViewController:theController animated:YES];
}
[theController release];
}
}
and in your viewControllers:
- (void)viewDidLoad {
[super viewDidLoad];
MyAppDelegate *delegate = (MyAppDelegate *) [[UIApplication sharedApplication] delegate];
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeInfoLight];
[infoButton addTarget:delegate
action:#selector(showHelp)
forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *infoItem = [[UIBarButtonItem alloc] initWithCustomView:infoButton];
self.navigationItem.rightBarButtonItem = infoItem;
[infoItem release];
}
Didn't try it but it should work.

How to use a UIAlert to open a NIB or UIView

Here is my code so far I can get a URL to work but I want to load a nib from this Alert tab
- (IBAction)aboutAction { // The action called when the about button is clicked.
UIAlertView * aboutView = [[UIAlertView alloc] initWithTitle:#"Alert:" // Create a new UIAlertView named aboutScreen, and allocate it. Set the title to "About"
message:#"MESSAGE GOES HERE"
delegate:self
cancelButtonTitle:#"Got It Thanks!"
otherButtonTitles:#"Donate Now", nil];
[aboutView show]; // Show the UIAlertView on the screen.
[aboutView release]; // Release the UIAlertView from the memory.
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
if(buttonIndex == 1) { //Not sure what to do here.
}
}
-(void) alertView:(UIAlertView *) alertview clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (buttonIndex) {
case 1: {
Accidenthelpercall *help = [[Accidenthelpercall alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:help animated:NO];
}
case 2: {
Accidentdamagecar *damagecar = [[Accidentdamagecar alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:damagecar animated:NO];
}
}
-(void) alertView:(UIAlertView *) alertview clickedButtonAtIndex:(NSInteger)buttonIndex {
switch (buttonIndex) {
case 1: {
Accidenthelpercall *help = [[Accidenthelpercall alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:help animated:NO];
[help release];
}
case 2: {
Accidentdamagecar *damagecar = [[Accidentdamagecar alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:damagecar animated:NO];
[damagecar release];
}
}