Action Sheet Within ActionSheet - iphone

am new to Objective C and iPhone Development.
Kindly tell me how can i add an action sheet within action sheet.
Like when i tap a button an action sheet is opened and then I clicked the first ButtonIndex of action another action sheet appears.
Kindly mention the complete code.
Thanks

Use the UIActionSheet delegate method:
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
if (buttonIndex == 0) { // Add an action sheet for one of these buttons -> maybe here if you want...
NSLog(#"You clicked the first button...");
UIActionSheet *popupQuery = [[UIActionSheet alloc] initWithTitle:#"Another action sheet"
delegate:self cancelButtonTitle:#"Cancel Button" destructiveButtonTitle:#"Destructive"
otherButtonTitles:#"Other Button 1", nil];
popupQuery.actionSheetStyle = UIActionSheetStyleBlackOpaque;
[popupQuery showInView:self.view];
[popupQuery release];
}
else {
NSLog(#"Dismissing action sheet");
}
}

All you want to do is dismiss the first UIActionSheet and show another UIActionSheet in it's place. In other words, you don't want to show a UIActionSheet within another UIActionSheet -- you want to show a UIActionSheet after a different UIActionSheet has been dismissed.
To find out when an action sheet is being dismissed, you should implement the UIActionSheetDelegate protocol. For example:
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex {
// first action sheet is dismissed
// show a new action sheet here
}

Related

How the UIActionSheet works?

When popping a view I want to save some data, by asking confirmation. I'm asking confirmation using UIActionSheet. But irrespective of my response in action sheet, the view is changing in background, it creates some problem for me to use the response. I'm using navigation controller to switch views. How can I solve this
TIA
Better option is to use uialertview for asking confirmation.To do this follow this step:
Insure your header file contains the following:
#interface YourViewController : UIViewController <UIAlertViewDelegate>
Now when asked confirmation add this code:
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message" message:#"Are You Sure" delegate:self cancelButtonTitle:#"YES" otherButtonTitles:#"NO", nil];
[alert show];
[alert release];
Now after pressing one button below delegate will be called so add in .m file of app
- (void)alertView:(UIAlertView *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
// the user clicked one of the YES/NO buttons
if (buttonIndex == 0)
{
NSLog(#"NO button pressed");
}
else
{
//Save data here
NSLog(#"YES button pressed");
}
}
#PooLas If I understood you correctly, You use uiactionsheet for user confirmation, while in background (actually under actionsheet) you change view controllers. Well, you can't do that, because delegate must be attached to controller which shows it up (if i am wrong, correct me). So when you click button, you can only first dismiss actionsheet and then change view controller, but not opposite – PooLaS

View locked out after UIActionSheet or UIAlertView (iPhone / iPad)

I'm having some trouble with either a UIAlertView or UIActionSheet stealing the focus and not letting go.
To elaborate, I have a setup whereby a user presses a button. This then displays a UIAlertView with a UITextField. When the user presses the 'Ok' button a UIActionSheet is displayed (called from the UIAlertView delegate method) confirming something with the user. However when they press one of the buttons the UIActionSheet goes away but the focus doesn't get returned to the main view.
I have been playing around and whatever I seem to do I always end up with my main UIView being covered with a layer like this (obviously you can seem my view through the layer). I have tried removing all subviews of the view but it didn't have any success.
Please can someone help me out?
Here is the source code:
// This method displays the UIAlertView which contains a UITextView linked up to a
// UIPickerView.
- (IBAction)buttonPressed:(id)sender
{
UIAlertView *deleteAlert = [[UIAlertView alloc] initWithTitle:#"Delete Something"
message:#"Select something to delete:"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles:#"Ok", nil];
deleteAlert.alertViewStyle = UIAlertViewStylePlainTextInput;
deleteAlert.tag = kDeleteAlert;
deleteTextField = [deleteAlert textFieldAtIndex:0];
[pickerView reloadAllComponents];
deleteTextField.inputView = pickerView;
[deleteAlert show];
}
// The UIAlertView delegate method is then used to display a UIActionSheet to confirm
// whether the user wants to proceed.
- (void) alertView:(UIAlertView *)alert clickedButtonAtIndex:(NSInteger)buttonIndex
{
UIActionSheet *confirmDelete = [[UIActionSheet alloc] initWithTitle:#"Delete blah?"
delegate:self
cancelButtonTitle:#"No"
destructiveButtonTitle:#"Yes"
otherButtonTitles:nil];
confirmDelete.actionSheetStyle = UIActionSheetStyleBlackOpaque;
[confirmDelete showInView:self.parentViewController.tabBarController.view];
}
// Then the focus should be returned to the original view (i.e. where the first button
// was pressed to launch the UIAlertView. However the focus is still locked and the
// view appears slightly dimmed around the edges.
-(void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == actionSheet.destructiveButtonIndex)
{
// Do some stuff ...
}
}
I think your issue is a result of the deleteAlert alert view not being dismissed when the actionSheet is called.
I sounds to me like the alert view still has focus but is in an unknown state, because it hasn't been dismissed, but you have done something with it's button press.
Presumably, you want to dismiss the alert view when the action sheet is presented? Then when the action sheet is dismissed, you get back to your main view? So, the order you want:
1) Present alert view
2) If a button on the alert view is pressed, it notifies it's delegate using - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
3) Dismiss the alertView - (void)dismissWithClickedButtonIndex:(NSInteger)buttonIndex animated:(BOOL)animated and present the action sheet.
3) When the action sheet is used, it calls it's delegate method - (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex and within that method, dismiss it, or whatever else you need to do.
You would put all of these delegate methods in your original calling viewcontroller, conforming it to <UIAlertViewDelegate, UIActionSheetDelegate>.
You will need to make the original viewcontroller the delegate of the alert view AND the action sheet when you create them. I hope this makes sense.
More information http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAlertView_Class/UIAlertView/UIAlertView.html
I would say it's probably b/c you are not resigning the first responder on the UITextField that is inside the UIAlertView. Make sure that before you show your UIActionSheet you do
[myTextField resignFirstResponder];

UIActionSheet from UIAlertView

I'm trying to show a UIActionSheet when the user touches a button in a UIAlertView:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
UIActionSheet *actionSheet = ...
[actionSheet showFromTabBar:self.tabBarController.tabBar];
}
}
When the action sheet is shown the alert view is still on the screen behind the action sheet, and when I touch a button in the action sheet - the action sheet disappears but the whole screen is dimmed with the alert view still on and I can't dismiss it.
I tried several things, such as showing the action sheet after a short delay or dismissing the alert view programmatically, but nothing worked. In the best case (dismissing the alert view programmatically) the alert view did disappear after a somewhat-strange transition but I got a "wait-fence failed to receive reply" error in the log when it did.
How can I show an action sheet from an alert view in an orderly manner?
In this case, you should use
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
method rather than,
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
so your code wil be:
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
UIActionSheet *actionSheet = ...
[actionSheet showFromTabBar:self.tabBarController.tabBar];
}
}
Thanks,
Just call dismissWithClickedButtonIndex:animated: method for UIAlertView
if (buttonIndex == 0)
{
[alertView dismissWithClickedButtonIndex:0 animated:YES];
UIActionSheet *actionSheet = ...
[actionSheet showFromTabBar:self.tabBarController.tabBar];
}

Action sheet doesn't show Cancel button on iPad

On the iphone, this code shows the cancel button:
- (IBAction)buttonPressed
{
UIActionSheet *actionSheet = [[UIActionSheet alloc]
initWithTitle:#"Are you sure?"
delegate:self
cancelButtonTitle:#"No way!"
destructiveButtonTitle:#"Yes, I'm sure!"
otherButtonTitles:nil];
[actionSheet showInView:self.view];
[actionSheet release];
}
But on the iPad, only the destructive button shows.
What's the problem?
This is part of the UI design and guidlines. Under 'Action Sheet' they say:
Do not include a Cancel button,
because people can tap outside the
popover to dismiss the action sheet
without selecting one of the other
alternatives.
It looks like the SDK hide the button for you on purpose. I'm not sure there is a solution, but maybe you could add your own button and set the cancelButtonIndex to match. Or you could switch to UIAlertView.
In iOS 5, this worked for me.
- (void)manualAddModel
{
UIActionSheet *popupQuery = [[UIActionSheet alloc] initWithTitle: #"Select Equipment Type"
delegate: self
cancelButtonTitle: #"Cancel"
destructiveButtonTitle: nil
otherButtonTitles: #"Add Boiler", #"Add Furnace", nil];
popupQuery.actionSheetStyle = UIActionSheetStyleDefault;
[popupQuery addButtonWithTitle:#"Cancel"];
[popupQuery showInView:self.view];
}
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0)
{
NSLog(#"Add Boiler");
}
else if (buttonIndex == 1)
{
NSLog(#"Add Furnace");
}
else if (buttonIndex == 2)
{
NSLog(#"Cancel Button Clicked");
}
}
Normally, tapping outside the actionsheet will serve the same purpose in iPad.
It looks like in iOS 4.2.1 you can manually add your own Cancel button like a normal button:
[actionSheet addButtonWithTitle:#"Cancel"];
And then set:
actionSheet.cancelButtonIndex = <your index>;
You won't get the red cancel button, but you will get either a blue or black one depending on your UIActionSheetStyle setting. In any event, it is pretty clearly distinguishable from the normal buttons and does correctly cancel.
Note that in my case I am showing an action sheet from within a popover controller, your results may vary in other scenarios.
I was able to solve this by setting the actionSheetStyle:
actionSheet.actionSheetStyle = UIActionSheetStyleBlackOpaque;
UIActionSheetStyleBlackTranslucent also works. I am displaying the action sheet from a modal view controller which I guess is not technically a "popovercontroller" like the guidelines say but not seeing a Cancel button on the action sheet doesn't look right when it appears on top of the modal view. All the user sees is one scary red button with no visible alternative.
Maybe I could change the modal view controller to a popovercontroller but then it wouldn't be modal which it needs to be.
--Update--
Well it was fun while it lasted but this no longer works in iOS 4.2.
I switched to using a UIAlertView instead of a UIActionSheet.
I no longer get a cool red button but it gets the job done.
I had the same issue when I tried to show ActionSheet in the View that was under another modal view, e.g. the view was invisible. Though the View wasn't nil looks like deep in framework it means so when it's not shown.
I solved the problem by setting a different UIModalPresentationStyle modalPresentationStyle property so the view became visible.
view.modalPresentationStyle = UIModalPresentationFormSheet;
According to iOS standard Cancel button is not displayed in UIActionSheet when displayed in iPad since UIActionSheet can be cancelled (Hide) by simply tapping any where outside ActionSheet region. In case of iPhone UIActionSheet will contain Cancel button.
Refer this link for further information UIActionSheet Cancel button in iPad

- (void)alertViewCancel:(UIAlertView *)alertView is not called

I've got the problem that the UIAlertViewDelegate method - (void)alertViewCancel:(UIAlertView *)alertView is not called when I cancel a AlertView with it's cancel button.
Weird is that the delegate method - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex works perfectly.
Does anyone have an idea?
Thanks in advance
Sean
- (void)alertViewCancel:(UIAlertView *)alertView
{
if(![self aBooleanMethod])
{
exit(0);
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
//some code
}
I call this when a button is clicked:
- (void)ImagePickDone
{
UIAlertView *alertDone = [[UIAlertView alloc]
initWithTitle:#"Done"
message:#"Are u sure?"
delegate:self
cancelButtonTitle:#"Cancel"
otherButtonTitles: #"Yes", nil];
[alertDone show];
[alertDone release];
}
The alertViewCancel is used for when the system dismisses your alert view, not when the user presses the "Cancel" button. Quote from apple docs:
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.
If you want to capture when the user presses the "Cancel" button you should use the clickedButtonAtIndex method and check that the index corresponds to the index for the cancel button. To obtain this index use:
index = alertDone.cancelButtonIndex;
You can handle the Cancel at the index 0 of this delegate:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex == 0){
//cancel button clicked. Do something here.
}
else{
//other button indexes clicked
}
}
This can be improved in two ways. First, it only handles the case that the user actually clicked a button. It doesn't handle the situation that [myAlert dismissWithClickedButtonIndex:] is called, or that the alert is dismissed in some other way. Second, button 0 is not necessarily the cancel button. In an alert with two buttons, the left one is at index 0, and the right one is at index 1. If you changed the titles so that the right button says "Cancel", then button 1 is logically the Cancel button. Instead of "willDismiss" you can implement "didDismiss" which will be called after the dialog has disappeared and not before.
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex
{
if (buttonIndex == alertView.cancelButtonIndex)
{
//cancel button clicked. Do something here.
}
else
{
//other button indexes clicked
}
}