UIAlertController is Crashed (iPad)
Solution 1
To keep it device independent, rather use it as shown in the snippet below. This code will return nil for popoverPresentationController on an iPhone / compact size device, so you can safely use it in universal projects.
if let popoverPresentationController = shareMenu.popoverPresentationController {
popoverPresentationController.sourceView = self.view
popoverPresentationController.sourceRect = sender.bounds
}
self.presentViewController(shareMenu, animated: true, completion: nil)
Solution 2
try this code:
shareMenu.popoverPresentationController.sourceView = self.view
shareMenu.popoverPresentationController.sourceRect = CGRectMake(self.view.bounds.size.width / 2.0, self.view.bounds.size.height / 2.0, 1.0, 1.0)
self.presentViewController(shareMenu, animated: true, completion: nil)
Solution 3
Swift 4
popoverPresentationController.permittedArrowDirections = .init(rawValue: 0)
popoverPresentationController.sourceView = self.view
popoverPresentationController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
Solution 4
reference: ActionSheet Popover on iPad in Swift
create popoverController :
let alertController = UIAlertController(title: nil, message: "Alert message.", preferredStyle: .actionSheet)
self.present(alertController, animated: true, completion: nil)
if you want show alert with indicator view should:
if let popoverController = alertController.popoverPresentationController {
popoverController.barButtonItem = sender
}
show alert in center:
if let popoverController = alertController.popoverPresentationController {
popoverController.sourceView = self.view
popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
}
center no indicator:
if let popoverController = alertController.popoverPresentationController {
popoverController.sourceView = self.view
popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
popoverController.permittedArrowDirections = []
}
Solution 5
I am also face same issue and finally got the solution. Here is my solution for Objective-C:
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Select you option:"
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *action = [UIAlertAction actionWithTitle:@“share”
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
// do other things
}];
[alertController addAction:action];
UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
}];
[alertController addAction:cancelAction];
// Remove arrow from action sheet.
[alertController.popoverPresentationController setPermittedArrowDirections:0];
//For set action sheet to middle of view.
CGRect rect = self.view.frame;
rect.origin.x = self.view.frame.size.width / 20;
rect.origin.y = self.view.frame.size.height / 20;
alertController.popoverPresentationController.sourceView = self.view;
alertController.popoverPresentationController.sourceRect = rect;
[self presentViewController:alertController animated:YES completion:nil];
Admin
Updated on July 09, 2022Comments
-
Admin almost 2 years
I am using Xcode 6 to develop an iOS Application.
When I used
UIAlertController
, it can be worked well on iPhone 6 simulator, but crashes on iPad simulator.My problem while clicking "share", then it could be crashed. How could I solve it?
Here is my Code:
override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [AnyObject] { var shareAction = UITableViewRowAction(style: UITableViewRowActionStyle.Default, title: "Share", handler: { (action:UITableViewRowAction!, indexPath:NSIndexPath!) -> Void in let shareMenu = UIAlertController(title: nil, message: "Share using", preferredStyle: .ActionSheet) let twitterAction = UIAlertAction(title: "Twitter", style: UIAlertActionStyle.Default, handler: nil) let facebookAction = UIAlertAction(title: "Facebook", style: UIAlertActionStyle.Default, handler: nil) let emailAction = UIAlertAction(title: "Email", style: UIAlertActionStyle.Default, handler: nil) let cancelAction = UIAlertAction(title: "Cancel", style: UIAlertActionStyle.Cancel, handler: nil) shareMenu.addAction(twitterAction) shareMenu.addAction(facebookAction) shareMenu.addAction(emailAction) shareMenu.addAction(cancelAction) self.presentViewController(shareMenu, animated: true, completion: nil) } )
Xcode showed this message:
******Terminating app due to uncaught exception 'NSGenericException', reason: 'Your application has presented a UIAlertController (<UIAlertController: 0xaf71c80>) of style UIAlertControllerStyleActionSheet. The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover. You must provide location information for this popover through the alert controller's popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem. If this information is not known when you[![enter image description here][1]][1] present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.' *** First throw call stack: ( 0 CoreFoundation 0x0023c746 __exceptionPreprocess + 182 1 libobjc.A.dylib 0x01c7aa97 objc_exception_throw + 44 2 UIKit 0x012c4062 -[UIPopoverPresentationController presentationTransitionWillBegin] + 3086 3 UIKit 0x00bda174 __71-[UIPresentationController _initViewHierarchyForPresentationSuperview:]_block_invoke + 1549 4 UIKit 0x00bd8247 __56-[UIPresentationController runTransitionForCurrentState]_block_invoke + 198 5 UIKit 0x00c0d31b __40+[UIViewController _scheduleTransition:]_block_invoke + 18 6 UIKit 0x00ac6862 ___afterCACommitHandler_block_invoke + 15 7 UIKit 0x00ac680d _applyBlockToCFArrayCopiedToStack + 415 8 UIKit 0x00ac6622 _afterCACommitHandler + 549 9 CoreFoundation 0x0015d86e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30 10 CoreFoundation 0x0015d7b0 __CFRunLoopDoObservers + 400 11 CoreFoundation 0x001531ea __CFRunLoopRun + 1226 12 CoreFoundation 0x00152a5b CFRunLoopRunSpecific + 443 13 CoreFoundation 0x0015288b CFRunLoopRunInMode + 123 14 GraphicsServices 0x047b82c9 GSEventRunModal + 192 15 GraphicsServices 0x047b8106 GSEventRun + 104 16 UIKit 0x00a9c106 UIApplicationMain + 1526 17 Mars I 0x0001c724 main + 180 18 libdyld.dylib 0x02392ac9 start + 1 19 ??? 0x00000001 0x0 + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException******
-
deloki over 7 yearsjust had this issue on iOS10, dont think its fixed
-
Harish over 7 yearsActually, you don't need to perform the
if let
check as if thepopoverPresentationController
isnil
nothing will be set. -
Adam Smaka over 7 years.sourceView should be sender, not self.view in order to display proper arrow direction
-
Harry Bloom about 7 yearsyep, just
popoverPresentationController?.sourceView = self.view
andpopoverPresentationController?.sourceRect = sender.bounds
will suffice -
SpaceTrucker almost 7 yearscurious why we're dividing by 20 here. I tried 2.0 and that puts it in the bottom right. Something about the geometry is unclear.
-
Ichor de Dionysos over 6 yearsWhat exactly is the
sender
in this case? Is it the view on which the action was performed? -
Karoly Nyisztor over 6 yearsYes, the sender is the UIControl or UIView that fired the action.
-
kurtanamo over 6 yearsSwift 4 for remove arrow:
popoverPresentationController.permittedArrowDirections = .init(rawValue: 0)
-
Cerlin over 6 yearsCan you explain
CGRectMake(self.view.bounds.size.width / 2.0, self.view.bounds.size.height / 2.0, 1.0, 1.0)
? -
Cœur about 5 years@CerlinBoss this defines a 1 pixel square in the middle of the view as to where the menu arrow should point to.