Presenting a view controller modally from an action sheet's delegate in iOS8 - iOS11
Update: As of iOS 9 SDK, UIActionSheet
is deprecated, so do not expect a fix regarding this issue. It is best to start using UIAlertController
when possible.
The problem seems to come from Apple's switch to using UIAlertController
internally to implement the functionality of alert views and action sheets. The issue is seen mostly on iPad and action sheets, because on iPad, action sheets are presented as a popover within a specified view, and what Apple does is travel the responder chain until it finds a view controller and calls presentViewController:animated:completion:
with the internal UIAlertController
. The problem is less obvious on iPhone and with alert views, because there Apple actually creates a separate window, an empty view controller and presents the internal UIAlertController
on top of that, so it seems to not interfere with other presentation.
I have opened bug report for this issue: rdar://17742017. Please duplicate it and let Apple know this is a problem.
As a workaround, I recommend delaying the presentation until the next runloop, using the following method:
dispatch_async(dispatch_get_main_queue(), ^ {
[self presentViewController:vc animated:YES completion:nil];
});
UIAlertController Error When called in a modal presented view controller in swift
Try to add it in main operation queue.
dispatch_async(dispatch_get_main_queue()) {
self.presentViewController(myAlert, animated: true, completion: nil)
}
Check this relative question : Presenting a view controller modally from an action sheet's delegate in iOS8 - iOS10
PresentViewController: animated not displaying on iPad
I missed this error message at first:
Warning: Attempt to present <SLComposeViewController: 0x175d6560> on <ScheduleTableViewController: 0x17538c20> which is already presenting (null)
That lead me to discussion of same problem in a different context here.
Resolved the issue by suggested work around:
dispatch_async(dispatch_get_main_queue(), ^ {
[self presentViewController:tweetSheet animated:YES completion:nil];
});
Change Action sheet popover arrow in iOS8
Solution :use below line for remove arrow from action sheet
[yourAlertController.popoverPresentationController setPermittedArrowDirections:0];
Sample
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Test Action Sheet" message:@"Message" preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *cancelAction = [UIAlertAction
actionWithTitle:@"Cancel"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *action)
{
NSLog(@"Cancel action");
}];
UIAlertAction *okAction = [UIAlertAction
actionWithTitle:@"Ok"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
NSLog(@"OK action");
}];
UIAlertAction *otherAction = [UIAlertAction
actionWithTitle:@"Other"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action)
{
NSLog(@"Otheraction");
}];
[alertController addAction:okAction];
[alertController addAction:otherAction];
[alertController addAction:cancelAction];
// Remove arrow from action sheet.
[alertController.popoverPresentationController setPermittedArrowDirections:0];
//For set action sheet to middle of view.
alertController.popoverPresentationController.sourceView = self.view;
alertController.popoverPresentationController.sourceRect = self.view.bounds;
[self presentViewController:alertController animated:YES completion:nil];
Output
UIAlertContoller ios8 present in UIWindow
You can create your own UIWindow and put whatever you want in it, and it will be above everything including the status bar. I don't have a handy like to an example but you can find them. Look for examples of building your own UIAlertViewController. I used this at a previous job to build an alert that could have any number of items in it.
definesPresentationContext = true in container view still allows modal animations over background views
So you are saying that your view controller hierarchy is
RootViewController
ViewController1
In that case, run this code inside ViewController1:
let vc = // ViewController2 instance, obtained somehow
vc.modalTransitionStyle = .coverVertical
self.definesPresentationContext = true
vc.modalPresentationStyle = .currentContext
self.present(vc, animated: true)
You will see that only the area of ViewController1's view is involved in the transition.
Note that the clipsToBounds
of the container view must be set to true
. If there is no container view, add one (to provide the clipping) — though I believe, from your description, that there is one (i.e. that you configured this in a storyboard).
Related Topics
Attempting to Load the View of a View Controller While It Is Deallocating... Uisearchcontroller
Share Extension to Open Containing App
How to Detect Whether Custom Keyboard Is Activated from the Keyboard's Container App
How to Load Local PDF in Uiwebview in Swift
Display Done Button on Uipickerview
Modal Segue, Navigation Bar Disappears
Ios: How to Find the Creation Date of a File
How to Use Static Cells in Uitableview Without Using Storyboards
How to Do Programmatically Gradient Border Color Uibutton with Swift
How to Combine Two Dictionary Instances in Swift
How to Make a Function Execute Every Second in Swift
Presenting a View Controller Modally from an Action Sheet's Delegate in iOS8 - iOS11
How to Enable Arc Project-Wide in Xcode 4.2
How to Set Cmake_C_Compiler and Cmake_Cxx_Compiler for Building Assimp for iOS
Wireless iPhone App Distribution - Problem with Itms-Services Protocol