Swift UIAlertController – > ActionSheet iPad的iOS8崩溃

目前我遇到了我的ActionSheet很大的麻烦。 在iPhone上它工作的很好,但在iPad上它只会崩溃

我只用一个button创build一个新项目

import UIKit extension ViewController : UIActionSheetDelegate { func actionSheet(actionSheet: UIActionSheet, didDismissWithButtonIndex buttonIndex: Int) { if actionSheet.tag == 0 { if buttonIndex == 1 { // doing something for "product page" } else if (buttonIndex == 2) { // doing something for "video" } } } } class ViewController: UIViewController, UIActionSheetDelegate { @IBAction func test(sender: AnyObject) { let systemVersion: NSInteger = (UIDevice.currentDevice().systemVersion as NSString).integerValue if systemVersion < 8 { // iOS7: let action:UIActionSheet = UIActionSheet(title: "Change Map Type", delegate: self, cancelButtonTitle: "Back", destructiveButtonTitle: nil, otherButtonTitles: "Product Page", "Video") action.tag = 0 action.showInView(self.view) } else { // iOS8: let alertController: UIAlertController = UIAlertController(title: "Change Map Type", message: nil, preferredStyle: UIAlertControllerStyle.ActionSheet) let cancelAction: UIAlertAction = UIAlertAction(title: "Back", style: UIAlertActionStyle.Cancel, handler: nil) let button1action: UIAlertAction = UIAlertAction(title: "Product Page", style: UIAlertActionStyle.Default, handler: { (action: UIAlertAction!) -> () in // doing something for "product page" }) let button2action: UIAlertAction = UIAlertAction(title: "Video", style: UIAlertActionStyle.Default, handler: { (action: UIAlertAction!) -> () in // doing something for "video" }) alertController.addAction(cancelAction) alertController.addAction(button1action) alertController.addAction(button2action) self.presentViewController(alertController, animated: true, completion: nil) } } override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. } } 

正如我所说的iphone它的工作原理,但如果我点击iPad上的button应用程序崩溃

2014-09-25 14:54:52.784testing[9541:1970048] *因未捕获exception'NSGenericException'而终止应用程序,理由是:'您的应用程序提供了样式为UIAlertControllerStyleActionSheet的UIAlertController()。 具有此样式的UIAlertController的modalPresentationStyle是UIModalPresentationPopover。 您必须通过警报控制器的popoverPresentationController为此popup窗口提供位置信息。 您必须提供sourceView和sourceRect或barButtonItem。 如果在显示警报控制器时未知这些信息,则可以在UIPopoverPresentationControllerDelegate方法的-prepareForPopoverPresentation中提供。 *第一次调用堆栈:(0 CoreFoundation 0x00613df6 exceptionPreprocess + 182 1 libobjc.A.dylib
0x01fdaa97 objc_exception_throw + 44 2 UIKit
0x0164da37 – [UIPopoverPresentationController presentationTransitionWillBegin] + 3086 3 UIKit
0x00f54f75 __71- [UIPresentationController _initViewHierarchyForPresentationSuperview:] _ block_invoke + 1666 4 UIKit 0x00f53554 __56- [UIPresentationController runTransitionForCurrentState] _block_invoke + 226 5 UIKit
0x00f8721b __40 + [UIViewController _scheduleTransition:] _ block_invoke + 18 6 UIKit 0x00e4d62e ___afterCACommitHandler_block_invoke + 15 7 UIKit 0x00e4d5d9 _applyBlockToCFArrayCopiedToStack + 415 8 UIKit
0x00e4d3ee _afterCACommitHandler + 545 9 CoreFoundation
0x00536fbe __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 30 10 CoreFoundation 0x00536f00 __CFRunLoopDoObserver + 400 11 CoreFoundation 0x0052c93a __CFRunLoopRun + 1226 12 CoreFoundation 0x0052c1ab CFRunLoopRunSpecific + 443 13 CoreFoundation
0x0052bfdb CFRunLoopRunInMode + 123 14 GraphicsServices
0x0438424f GSEventRunModal + 192 15个graphics服务
0x0438408c GSEventRun + 104 16 UIKit
0x00e23e16 UIApplicationMain + 1526 17testing
0x00085e9e top_level_code + 78 18testing
0x00085edb main + 43 19 libdyld.dylib
0x0273eac9开始+ 1 20 ???
0x00000001 0x0 + 1)libc ++ abi.dylib:以NSExceptiontypes的未捕获exception终止

项目可以在https://www.dropbox.com/s/54jqd8nsc67ll5g/test.zip?dl=0find下载和尝试。

该错误消息告诉您,您需要给警报控制器的popoverPresentationController一个位置,以便它可以正确定位。 这很容易做 – 只要检查是否有一个popover控制器,并添加发件人作为源。

如果你的button是一个UIBarButtonItem

 if let popoverController = alertController.popoverPresentationController { popoverController.barButtonItem = sender } self.presentViewController(alertController, animated: true, completion: nil) 

除此以外:

 if let popoverController = alertController.popoverPresentationController { popoverController.sourceView = sender popoverController.sourceRect = sender.bounds } self.presentViewController(alertController, animated: true, completion: nil) 

尝试这个

 alertController.popoverPresentationController?.sourceView = self.view 

内特·库克是完全正确的,但是我会这样做,所以我检测它是iPad还是iPhone。

这是为barButtonItem

 if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad ){ if let currentPopoverpresentioncontroller = alertController.popoverPresentationController{ currentPopoverpresentioncontroller.barButtonItem = sender as! UIBarButtonItem currentPopoverpresentioncontroller.permittedArrowDirections = UIPopoverArrowDirection.down; self.present(alertController, animated: true, completion: nil) } }else{ self.present(alertController, animated: true, completion: nil) }