My UIActionSheet acting like non-modal? - iphone

NSLog(#"Display Action Sheet");
UIActionSheet *alert = [[UIActionSheet alloc] initWithTitle:#"Warning" delegate:self cancelButtonTitle:#"Proceed" destructiveButtonTitle:#"Cancel (current data will be discard)" otherButtonTitles:nil];
[alert showInView:[self view]];
[alert release];
NSLog(#"Action Sheet Released");
This is my code that creates an action sheet. Before I see the action sheet, both "Display Action Sheet" and "Action Sheet Released" get output to the debugger console. Actually other codes that I want to execute AFTER I receive input from user are all executed before I am presented the action sheet.
This is rather weird. I thought I could use action sheet to execute codes based on user's input.

Action sheets aren't modal. Pretty much nothing in iOS is. You need to handle whatever the user chooses in the sheet in one of the UIActionSheetDelegate methods, like -actionSheet:clickedButtonAtIndex:.

Make sure you have the UIActionSheetDelegate in your header.

If I want the answer to a question without the user allowing the option of cancel, I do something like this (key is : "if (buttonIndex == -1) performSelector")... Basically just loop till happy...
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (debug==1) {
NSLog(#"Running %# '%#'", self.class, NSStringFromSelector(_cmd));
}
if (buttonIndex == -1) {
[self performSelector:#selector(selectDb) withObject:nil afterDelay:0.1];
} else {
[DataLayer selectDatabase: buttonIndex];
}
}
- (void) selectDb {
if (![DataLayer hasSelectedDatabase]) {
actionSheet = [[UIActionSheet alloc] initWithTitle:#"Filter" delegate:self cancelButtonTitle:nil destructiveButtonTitle:nil otherButtonTitles:#"Main", #"Training", #"Test 1", #"Test 2", #"Test 3", #"Test 4", nil];
[actionSheet showInView:[self view]];
}
}

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.

How to add a confirming pop up window in objective?

like JOptionPane in java,
when user do something.
and i ask for confirmation like,
are you sure you want to delete file?? or whatever the case is.
user confirms it
then i detect what user has chosen between both buttons
then i do something according to user choice
is there anything like this in objective c ??
links plz and some guidelines
thank you every one
You are looking for UIAlertView controller.
I believe that you want UIActionSheet, which is what Apple Recommends for user choice:
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:#"Some Message" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:#"button To Destroy or nil" otherButtonTitles:#"Choice 1", #"Choice 2", #"Choice 3", nil];
What you want to do is check which button is being clicked under otherButtonTitles:
Something like this:
UIAlertView *yourAlert = [[UIAlertView alloc] initWithTitle:#"Your title" message:#"Some String" delegate:self cancelButtonTitle:#"Dismiss" otherButtonTitles:#"Confirm",nil];
[yourAlert show];
And remember to set the delegate to self.
Then:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0){
//'Dismissing' code here
}
if (buttonIndex == 1){
//Detecting whatever was under otherButtonTitles:
//Right now it's checking if the user clicked "Confirm" -> So here you can put whatever you need
NSLog(#"You clicked Confirm");
}
}
Under the conditionals, you are checking which button the user is clicking.

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.

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.

UIAlertView and detemining what is clicked

I have code that when a user hits the end of the game, it prompts them if the would like to play again:
-(void)showAlert
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#" B U S T E D ! "
message:#"Sorry, you busted!\n\nWant to try your luck 1 More Time! ?"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"New Game", nil];
[alert show];
[alert release];
}
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
// the user clicked one of the OK/Cancel buttons
if (buttonIndex == 0)
{
//here is where we can close it
}
if (buttonIndex == 1)
{
[self createNewGame];
}
}
Now I want to also do a check when a user first starts the app to see if a prior game file exists and if so ask if they want to continue. I know I can do via:
-(void)priorGameExists
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#" Previous Game Exists ! "
message:#"A previous game currently exists. Would you like to resume that game?"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Resumse", nil];
[alert show];
[alert release];
}
But how do I have it go to a new "custom" clickedButtonAtIndex? Am I correct in assuming it has something to do with setting a different delegate? And if so, how would I do that?
You don't necessarily need a different delegate. Read my answer to this question:
iPhone - Several UIAlertViews for a delegate
One solution is to declare some UIAlertView as private class instance like that:
#interface myViewControllerInterface : UIViewController {
#private
UIAlertView *newGameAlert;
UIAlertView *resumeGameAlert;
}
Then in your view controller you can create your alertViews using them:
-(void)showAlert {
newGameAlert= [[UIAlertView alloc] initWithTitle:#" B U S T E D ! "
message:#"Sorry, you busted!\n\nWant to try your luck 1 More Time! ?"
delegate:self cancelButtonTitle:#"Cancel"
otherButtonTitles:#"New Game", nil];
[newGameAlert show];
[newGameAlert autorelease];
}
-(void)priorGameExists {
resumeGameAlert = [[UIAlertView alloc] initWithTitle:#" Previous Game Exists ! "
message:#"A previous game currently exists. Would you like to resume that game?"
delegate:self cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Resumse", nil];
[resumeGameAlert show];
[resumeGameAlert autorelease];
}
And to finish you can make the difference between each alert view using their pointer:
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (actionSheet == newGameAlert ) {
//do something
} else if (actionSheet == resumeGameAlert ) {
//do something
}
}
You could use a different delegate but an easier way would be to set the tag property to a unique value. If tag was, say, 10 you'd know it was from the original alert and if it was 20 it would be from the priorGameExits question. (You should probably use constants of course.)
in your clickedButtonAtIndex method test the title of the incoming alertview.
if ([actionSheet.title isEqualToString:#" B U S T E D ! "]) {
// do some busted stuff here
else if ([actionSheet.title isEqualToString:#" Previous Game Exists ! "]) {
// do some previous game stuff here
}
You'll probably want to set those titles using static strings, so you only have the string in one place in your code, but this is basically how you'd do it.