2014-09-25 87 views
43

目前我遇到了很大的麻煩,我的ActionSheet。在iPhone上它的偉大工程,但在iPad上只崩潰Swift UIAlertController - > ActionSheet iPad iOS8崩潰

我創建了一個新的項目,只有一個按鈕

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上的按鈕應用崩潰與

2014年9月25日14:54:52.784測試[9541:1970048] *終止應用程序由於 未捕獲的異常 'NSGenericException',原因:「你的應用程序已 呈現的UIAlertController() 風格UIAlertControllerStyleActionSheet。具有這種風格的UIAlertController的 的modalPresentationStyle是UIModalPresentationPopover。您必須通過 控制器的popoverPresentationController爲此彈出窗口提供位置信息。您必須提供 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 __CFRunLoopDoObservers + 400 11的CoreFoundation 0x0052c93a __CFRunLoopRun + 1226 12的CoreFoundation 0x0052c1ab CFRunLoopRunSpecific + 443 13 CoreFoundation
0x0052bfdb CFRunLoopRunInMode + 123 14 GraphicsServices
0x0438424f GSEventRunModal + 192 15 GraphicsServices
0x0438408c GSEventRun + 104 16的UIKit
0x00e23e16 UIApplicationMain + 1526 17試驗
0x00085e9e top_level_code + 78 18測試
0x00085edb主+ 43 19 libdyld.dylib
0x0273eac9啓動+ 1 20 ???
00000001爲0x0 + 1)的libC++ abi.dylib:與未捕獲 異常類型NSException

項目的終止可以在https://www.dropbox.com/s/54jqd8nsc67ll5g/test.zip?dl=0找到用於下載和嘗試。

+0

該職位與我的回答非常相似...除了例外。 http://stackoverflow.com/questions/26037657/swift-uiactionsheet-crashes-on-ipad – holex 2014-09-25 13:22:17

+0

是的,但它仍然崩潰 – 2014-09-25 13:23:18

+0

我會盡快更新我的答案... – holex 2014-09-25 13:24:18

回答

126

錯誤消息告訴您,您需要給警報控制器的位置popoverPresentationController以便它可以正確定位。這很容易做 - 只需檢查是否有popover控制器並添加發件人作爲源。

如果你的按鈕是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) 
+5

與迅速1.2,它現在需要做: popoverController.sourceView =發送者爲! UIView – Xerion 2015-06-19 18:10:35

+0

'popoverController.sourceRect = sender.bounds'使ActionSheet出現在iPad的左上角。相反,您可以使用'popoverController.sourceRect = sender.frame' – 2016-09-14 12:56:30

+0

sender.bounds'對我來說可以工作 - sourceRect是'在指定視圖中定位彈出窗口的矩形'。我認爲它是在sourceView的座標空間中,因此.bounds – leafcutter 2017-10-20 18:37:11

6

試試這個

alertController.popoverPresentationController?.sourceView = self.view 
+0

謝謝,它將我從崩潰中拯救出來,但它顯示在左上角...... – djdance 2017-11-11 16:12:14

1

內特 - 庫克是完全正確的,但是我會做,所以我發現,如果它是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) 
     } 
0

VAR actionSheet = UIAlertController(標題: 「請選擇相機或圖片庫」,留言: 「」,preferredStyle:.actionSheet)

if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad){ 
     actionSheet = UIAlertController(title: "Please Select Camera or Photo Library", message: "", preferredStyle: .alert) 
    } 

    actionSheet.addAction(UIAlertAction(title: "Upload a Photo", style: .default, handler: { (UIAlertAction) in 
     self.openPhotoLibrary() 
    })) 
    actionSheet.addAction(UIAlertAction(title: "Take a Photo", style: .default, handler: { (UIAlertAction) in 
     self.openCamera() 
    })) 
    actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) 
    self.present(actionSheet, animated: true, completion: nil)