问题
I have a problem with a popover. If I tap on a cell I will load a popover to select more details. Everything works fine, but when I press my cell again I receive every time the following message:
Warning: Attempt to present ModalTableViewController... on MainTableViewController... which is already presenting (null)
If I tap on another cell I will not get this Warning. Only if a tap the same row again.
I tried lots of things but I am not able to solve this problem. I load my popover with like this:
var popover: UIPopoverController!
var popoverContent: ModalTableViewController!
and on my cell tap:
popoverContent = self.storyboard.instantiateViewControllerWithIdentifier("ModalTableViewController") as ModalTableViewController
popoverContent.selectedQuestionID = indexPath!.row
popover = UIPopoverController(contentViewController: popoverContent)
popover.delegate = self
popover.presentPopoverFromRect(currentCell.LabelCellTitle.frame, inView: currentCell.LabelCellTitle.superview, permittedArrowDirections: UIPopoverArrowDirection.Left, animated: true)
And to dismiss
func popoverControllerDidDismissPopover(popoverController: UIPopoverController!) {
popover.dismissPopoverAnimated(false) // just to check
self.popover = nil
self.popoverContent = nil
}
Any ideas?
Edit:
If I check with:
if(self.popoverContent == nil) {
before opening it, I'll find out that it's not nil when I tap the same cell again.
Edit again:
I have the same problem if I create it with a little different setup:
Custom 1x1px Button. Connect popover with segue. On cell tap move button to cell and open popover.
So there is no code for opening the popover, only with storyboard editor.
I get the same error message (sometimes) just if I tap the same popover again.
回答1:
I'm not on swift yet, but for Objective-C, I ended up wrapping the presentViewController call in a performSelector call.
-(void) present
{
[self performSelector: @selector(ShowModalTableViewController) withObject: nil afterDelay: 0];
}
-(void) ShowModalTableViewController
{
[self presentViewController: ctrlModalTableViewController animated: true completion: nil];
}
回答2:
I had this issue because I was trying to perform segue / present from within:
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
I changed it to:
- (void)actionSheet:(UIActionSheet *)actionSheet didDismissWithButtonIndex:(NSInteger)buttonIndex
and it fixed it!
回答3:
This will work also:
dispatch_async(dispatch_get_main_queue(), ^ {
[self presentViewController:vc animated:YES completion:nil];
});
回答4:
It appears this is true of presenting anything over a popover. The reason all of the previous responses work is likely because whatever action is being taken happens before the popover (or activity sheet, or similar) is dismissed.
If you can, try dismissing the popover first, then presenting your modal.
回答5:
This is a iOS 8 issue on iPad actually and will not occur in iOS below 8. You can put a condition there:
if ([controller respondsToSelector:@selector(popoverPresentationController)])
{
// iOS8
controller.popoverPresentationController.sourceView = self.view; // or any of your UIiew
}
But consider Steve's point also (https://stackoverflow.com/a/26380194/362310) below with this code change.
回答6:
Easily just add this code snippet into ViewDidLoad()
of your main uiviewcontroller
definesPresentationContext = true
回答7:
This happens if a UIActionSheet is presented at the moment of new view controller presentation call, for example This code works for me
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[controller presentViewController:modalViewController animated:YES completion:NULL];
}];
回答8:
For me, this happened when I had two UIBarButton items as part of a NavigationItem and both had a triggered segue to open views as popover - with their own controllers. One popover would not automatically dismiss when tapping the other BarButtonItem. It would however dismiss when I tapped elsewhere outside the popover.
I ended up overriding UINavigationController and adding an extended version of presentViewController:animated:completion
/*
* Workaround for apparent bug in iPad that popover does not automatically dismiss if another bar button item is pressed
*/
- (void)presentViewController:(UIViewController *)viewControllerToPresent animated:(BOOL)flag completion:(void (^)(void))completion {
/*
* Make sure this runs in the main queue
*/
dispatch_async(dispatch_get_main_queue(), ^ {
if (
[self.presentedViewController isKindOfClass:[ViewController1 class]]
|| [self.presentedViewController isKindOfClass:[ViewController2 class]]
|| [self.presentedViewController isKindOfClass:[ViewController3 class]]
|| [self.presentedViewController isKindOfClass:[ViewController4 class]]
) {
[self dismissViewControllerAnimated:YES completion:^{
[super presentViewController:viewControllerToPresent animated:flag completion:completion];
}];
}
else {
[super presentViewController:viewControllerToPresent animated:flag completion:completion];
}
});
}
I believe the dispatch_async(dispatch_get_main_queue(), ^ {})
is not really necessary, I just added it as precaution.
回答9:
In my case, I accidentally link my button to an IBAction
and Storyboard Segue
with kind Present As Popover
at the same time. What I did to fix this was to remove my button's Touch Up Inside
event link to IBAction
and used only Storyboard Segue
.
来源:https://stackoverflow.com/questions/25213152/warning-attempt-to-present-modaltableviewcontroller-on-maintableviewcontroller