Swift UIAlertController - > ActionSheet iPad iOS8 S'écrase

actuellement, j'ai de gros problèmes avec mon ActionSheet. Sur iPhone il fonctionne très bien, mais sur iPad il ne se bloque

je crée un nouveau projet avec un seul bouton,

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.
    }

}

comme je l'ai dit sur l'iphone, il fonctionne, mais si je clique sur le bouton sur iPad L'application se bloque avec

2014-09-25 14:54:52.784 test[9541: 1970048] * fin de l'application en raison de uncaught exception 'NSGenericException', la raison: "Votre demande a présenté un UIAlertController () de style UIAlertControllerStyleActionSheet. Le modalPresentationStyle de un UIAlertController avec ce style est UIModalPresentationPopover. Vous doit fournir des informations de localisation pour cette liste par le biais de l'alerte contrôleur popoverPresentationController. Vous devez fournir un sourceView et sourceRect ou un barButtonItem. Si cette information est pas connu lorsque vous présentez le contrôleur d'alerte, vous pouvez fournir dans la méthode UIPopoverPresentationControllerDelegate - prepare forpopoverpresentation.' * First throw call stack: (0 CoreFoundation 0x00613df6 exception preprocess + 182 1 libobjc.A. dylib

0x01fdaa97 objc_exception_throw + 44 2 UIKit

0x0164da37 - [UIPopoverPresentationController presentationtransitiontransitionbegin] + 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 0x00e4d62f ___ Aftercacommithandler_block_invoke + 15 7 UIKit 0x00e4d5d9 _applyblocktofarraycopiedtostack + 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 test

0x00085e9e top_level_code + 78 18 test

0x00085edb principal + 43 19 libdyld.dylib

0x0273eac9 début + 1 à 20 ???

0 x 00000001 0 x 0 + 1 ) de la libc++abi.dylib: se terminant par uncaught exception du type NSException

Project peut être trouvé à https://www.dropbox.com/s/54jqd8nsc67ll5g/test.zip?dl=0 pour télécharger et essayer.

50
demandé sur Cœur 2014-09-25 16:56:17

4 réponses

le message d'erreur vous indique que vous devez donner au contrôleur d'alerte popoverPresentationController un emplacement pour qu'il puisse se positionner correctement. C'est facile à faire -- vérifiez simplement s'il y a un contrôleur popover et ajoutez l'expéditeur comme source.

si votre bouton est un UIBarButtonItem :

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

autrement:

if let popoverController = alertController.popoverPresentationController {
    popoverController.sourceView = sender
    popoverController.sourceRect = sender.bounds
}
self.presentViewController(alertController, animated: true, completion: nil)
135
répondu Nate Cook 2014-09-25 14:14:54

essayez cette

alertController.popoverPresentationController?.sourceView = self.view
7
répondu Beslan Tularov 2016-10-08 18:08:05

Nate Cook a totalement raison mais je le ferais donc je détecte si c'est iPad ou iPhone.

pour 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)
        }
2
répondu Tarvo Mäesepp 2016-11-01 22:44:14

var actionSheet = UIAlertController (titre:" Please Select Camera or Photo Library", message:"", 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)
0
répondu aakash tandukar 2018-01-15 09:08:42