I have an app originally developed for iPhone, with a MapViewController as the main screen, and a Help screen and Tutorial screen both called from within a UI ActionSheet. Works fine for the iPhone.
When run on an iPad, I can't get to the Help screen and get the following runtime error:
Warning: Attempt to present <HelpViewController: 0x177076c0> on <MapViewController: 0x177d7060> which is already presenting <UIAlertController: 0x17732620>
If I add the following line of code
[self dismissViewControllerAnimated:YES completion:nil];
then I do get to the Help screen, but with the following error:
Warning: Attempt to dismiss from view controller <MapViewController: 0x17d75660> while a presentation or dismiss is in progress!
When I exit the Help screen, the MapView does not come up, however selection a new baseMap brings it back to life.
So, the code runs fine on an iPhone. On the iPad I get an error that says
1) Don't open a new view with the UIAlertController active, or
2) Don't dismiss the view, because a dismiss is already in progress...
Sure seems like a timing problem to me, I've tried both a "sleep" statement and some code to provide a short delay, neither have helped.
Anyone have any ideas?
you have to set action sheet for iPad like below..
UIActionSheet *popup = [[UIActionSheet alloc] initWithTitle:#"Some Title" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:nil,nil];
if(!IS_IPad){
[popup showInView:[UIApplication sharedApplication].keyWindow];
}else{
[popup showFromRect:CGRectMake((CGRectGetWidth(self.view.frame)-200)/2, self.imgLogo.frame.origin.y,200, 200) inView:self.view animated:YES];
}
Surly your action sheet working in both.
This warning comes when you are trying to present/dismiss a view with animation while another animation is still in progress. This might be because while making a selection from UIActionsheet it animates and fades away and at the same time another viewcontroller is appearing with animation. It might help if you dismiss the view controller after delay of 0.2 seconds
Related
I am using an instance of UIActivityViewController in a universal app. It works absolutely perfectly on the iPad. Nearly, but not quite on the iPhone.
I present it using:
[self presentViewController:self.activityViewController animated:YES completion:nil];
It displays the available activities correctly and if I choose one, it works. I can then tap on the Share button again and repeat with the same or a different activity as often as I like, so long as I complete the activity.
If I Cancel from the UIActivityViewController, all is well; but if I cancel from, say, Mail or Message, the next time I tap on Share, nothing happens. If I get impatient and tap again, I get the following error:
'Application tried to present modally an active controller .'
I've tried dismissing the controller before presenting it a second time, but it doesn't think it is dismissible. I've also tried presenting it from the root/navigation controller as well as the tableviewcontroller, but get the equivalent error (i.e. the app tried to present the root controller).
I see there are lots of 'odd' problems with UIActivityViewController, but I can't see anything relevant to my problem.
The problem was due to the example code I'd used. I assumed that the dismiss code was being executed, when it wasn't!
I ended up implementing UIPopoverControllerDelegate and implementing:
- (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
[self setPopoverActivity:nil];
}
This fixed it!
this happened to me too, i saw your answer and i didn't understand it, because that "setPopoverActivity" wasn't recognized. So i started do some changes and this solved just doing the init of the "UIActivityViewController" inside the action void instead on viewDidLoad, where it was at first place.
- (void) flipView {
self.activityViewController =
[[UIActivityViewController alloc] initWithActivityItems:self.dataToShare
applicationActivities: nil];
self.activityViewController.excludedActivityTypes = #[UIActivityTypePrint,UIActivityTypeSaveToCameraRoll,UIActivityTypeAssignToContact, UIActivityTypeAddToReadingList];
[self presentViewController:self.activityViewController animated:YES completion:nil];
}
Hope it helps!
I am trying to create a UIActionSheet inside a UIViewController as follows:
discardAS = [[UIActionSheet alloc] initWithTitle:"title" delegate:self cancelButtonTitle:"Cancel" destructiveButtonTitle:"Discard" otherButtonTitles:nil];
discardAS.actionSheetStyle = UIActionSheetStyleDefault;
[discardAS showInView:[self view]];
When I evoke it - the entire screen "dim" (as if the actionsheet is actually in the foreground) - but I see no actionsheet.) It appears to be showing "offscreen".
WHen I try this on iOS7, I can see a white box shooting upwards, quickly going offscreen - as if it the ActionSheet is being placed above the top of the screen. When I click on the window, the dimness goes away, and all is normal - like iOS7 does if you tap out of the actionsheet and it goes away.
Thus, I am concluding the ActionSheet is being presented ABOUT (and out of) the confines of the screen.
I am also seeing the following on the console
Presenting action sheet clipped by its superview. Some controls might not respond to touches. On iPhone try -[UIActionSheet showFromTabBar:] or -[UIActionSheet showFromToolbar:] instead of -[UIActionSheet showInView:].
Both of which I tried, with the same results. Displaying self.view.frame shows a rect about 0,0,300,200 - so It's not grotesquely oversized.
Any idea why, or how to fix/debug?
For posterity - the answer was I had an "Extra View Controller" in my heirarchy - as described here: iOS 6: What changed that made this View Controller Hierarchy break?
I apologize if this has been asked but I can't seem to find it anywhere. I even recreated my issue in a demo project in case any of you want to see it first-hand, although I don't know where I should post it.
I have a xibless UINavigationController based app. Some of my child ViewControllers have a button on the right side at the top that then displays a UIActionSheet. My app is designed for iPhone and iPad, so when I get ready to display the UIActionSheet I do:
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:[NSString stringWithFormat:#"%# Menu", [self title]] delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:nil otherButtonTitles:#"Email", #"Print", nil];
[actionSheet setActionSheetStyle:UIActionSheetStyleDefault];
if ([actionSheet respondsToSelector:#selector(showFromBarButtonItem:animated:)])
[actionSheet showFromBarButtonItem:[[self navigationItem] rightBarButtonItem] animated:YES];
else [actionSheet showInView:[self view]];
[actionSheet release];
On iPad, I'm trying to show the UIActionSheet attached to the right bar button and on iPhone it should slide in from the bottom. All of this works beautifully.
Unfortunately, if you tap the button and show the menu on iPad, but then tap the back button on the top left side of the app, the menu doesn't dismiss. Instead UINavigationController dutifully pops back and the UIActionSheet is still there. If you try to tap something on the menu you of course get a crash. If the user would have tapped anything else on the screen instead of the Back button, the menu properly dismisses.
If you try this test on iPhone, everything works as expected. There is no issue.
My demo project has an AppDelegate and a ViewController and that's about it. The AppDelegate builds an NSDictionary of NSDictionaries just so I have a model I can recurse through to demonstrate the issue. The ViewController shows all of the keys of the dictionary and if the corresponding value is an NSDictionary, you can tap it to drill down.
This is an interesting problem. Here's what the UIActionSheet Class Reference has to say.
On iPad, this method presents the action sheet in a popover and adds
the toolbar that owns the button to the popover’s list of passthrough
views. Thus, taps in the toolbar result in the action methods of the
corresponding toolbar items being called. If you want the popover to
be dismissed when a different toolbar item is tapped, you must
implement that behavior in your action handler methods.
So when you display the action sheet, it's automatically creating a UIPopoverController and set the containing toolbar (or navigation bar) as the popover's passthrough views, allowing touch events to continue. I think the best bet is to create an instance variable for your action sheet and to force it to dismiss if it is visible in -viewWillDisappear:.
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
if (self.actionSheet.window) // If action sheet is on screen, window is non-nil
[self.actionSheet dismissWithClickedButtonIndex:self.actionSheet.cancelButtonIndex animated:animated];
}
Have you tried force-dismissing the ActionSheet on viewWillDisappear?
Try this:
// In MyViewController.m
- (void)viewWillDisappear:(BOOL)animated {
[actionSheet dismissWithClickedButtonIndex:nil animated:animated];
}
*The crash sounds like a possible EXC_BAD_ACCESS. You might be losing your pointer reference to 'actionSheet' when you change views due to your release. Might be good to hang on to a reference to actionSheet in your .h file and manage the timing of your release.
*Also see the docs for info about the dismiss message: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIActionSheet_Class/Reference/Reference.html
I have an UIViewController. Within it the user may launch an UIActionsheet or a popover. If the device rotates, the UIViewController is intentionally released. The problem is that the UIActionsheet / popover lives on and becomes a zombie to haunt me afterward. The user may click a button in the zombie and crash the application. I tried to call [actionsheet dismissWithClickedButtonIndex:0 animated:NO] in dealloc or shouldAutorotateToInterfaceOrientation. No effect. Appreciate any suggestions. Thanks.
I found the solution from this post: [dismiss actionsheet][1]
[1]: iPad crash with UIActionSheet displayed from child view controller. I made a mistake trying to recall the actionsheet by searching through the UIViewController view's subviews or calling the viewWithTag method. Strangely enough, it did return a non-nil object. But using this object to call dismissWithClickedButtonIndex does not work.
The autor of the post suggests using an UIActionSheet pointer and dismiss the actionsheet in viewWillDisapper works. For the above specific application, I found it worked better to dimiss the actionsheet in dealloc.
I have a UIBarButtonItem opening an action sheet to offer users choices about what to do. Everything works as expected unless I try to click on the "Cancel" button. The target of the button appears to have moved up from where it should be. I can only activate it by clicking somewhere in the middle of the "Cancel" and "Ok" buttons.
I've tried at action sheets in other applications and they work fine, so it's not just my big thumb. The action sheet is opening in a UIViewController
- (void)showOpenOptions
{
UIActionSheet *sheet = [[UIActionSheet alloc]
initWithTitle:NSLocalizedString(#"Open link in external application?", #"Open in external application")
delegate:self
cancelButtonTitle:NSLocalizedString(#"Cancel", #"Cancel")
destructiveButtonTitle:NSLocalizedString(#"Open Link", #"Open Link")
otherButtonTitles:nil];
[sheet showInView:self.view];
[sheet release];
}
Instead of passing the current view controller's view to the action sheet, use the showFromTabBar: method of UIActionSheet.
The Right Way
This will give the correct tappable area:
[actionSheet showFromTabBar:self.tabBarController.tabBar];
The Wrong Way
This will put the tappable area in the wrong place (if you're using a tab bar or toolbar):
[actionSheet showInView:self.view];
If you're using a toolbar, use the showFromToolbar: method instead. You'll need a reference to the toolbar, most likely an ivar
[actionSheet showFromToolbar:self.myToolbar];
My Old Answer Also works, but is hacky:
Just found a possible answer:
01-Dec-2008 10:22 PM Tom Saxton:
I looked at this bug some more, and it seems to be an issue with the tabbar.
If you call UIActionSheet's [sheet showInView:self.view] from a view controller that is a child of a UITabViewController, then the hit testing on the cancel button fails in that portion of the UIActionSheet that lies above the tabbar's view.
If you instead pass in the UITabBarController's view, then the UIActionSheet acts as expected.
NOTE: in iPhone OS 2.1 and earlier, the UIActionSheet came up from the top of the tab bar when you pass the child view, but in 2.2, it comes up from the bottom of the tab bar, and thus covers the tab view.
http://openradar.appspot.com/6410780
Edit: It works correctly when I change the view to be the tab bar's view
[sheet showInView:self.parentViewController.tabBarController.view];
I found an answer over here that works.
using: [filterActionSheet showInView:[self.view window]];
i tried a few ways to get to my tab bar and they way this app is set up it seem convoluted...
Instead use:
[sheet showFromTabBar:theTabBar];
Here is the fix.Try this:
[actionsheet showInView:[UIApplication sharedApplication].keyWindow];
I think a combination of three of the answers is the right way of handling this:
[actionSheet showFromTabBar:self.tabBarController.tabBar];
i.e., use showFromTabBar (that's why it exists) and you don't need the parentViewController as Nathan pointed out (in fact, self.parentViewController.tabBarController.tabBar returns nil for me.
FYI - had the same problem with UIDocumentInteractionController's actionsheet stepping on the tabbar. Used the following to fix.
UIViewController *parentView = [[self parentViewController] parentViewController];
[docController presentOptionsMenuFromRect: rect inView: parentView.view animated:YES];
write simplite code
actionSheet.actionSheetStyle = UIActionSheetStyleDefault;
this work fine