ActionSheet nie działa na iPadzie

86

Używam ActionSheet w mojej aplikacji. Na moim iPhonie działa, ale nie na symulatorze iPada.

to jest mój kod:

@IBAction func dialog(sender: AnyObject) {

    let optionMenu = UIAlertController(title: nil, message: "Choose Option", preferredStyle: .ActionSheet)
    let deleteAction = UIAlertAction(title: "Delete", style: .Default, handler: {

        (alert: UIAlertAction!) -> Void in
        println("Filtre Deleted")
    })

    let cancelAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: {
        (alert: UIAlertAction!) -> Void in
        println("Cancelled")
    })

    optionMenu.addAction(deleteAction)
    optionMenu.addAction(cancelAction)

    self.presentViewController(optionMenu, animated: true, completion: nil)
}

I mój błąd:

Zakończenie aplikacji z powodu nieprzechwyconego wyjątku „NSGenericException”, powód: „Twoja aplikacja przedstawiła UIAlertController () w stylu UIAlertControllerStyleActionSheet. ModalPresentationStyle elementu UIAlertController z tym stylem to UIModalPresentationPopover. Musisz podać informacje o lokalizacji dla tego okna popover za pomocą popoverPresentationController kontrolera alertów. Musisz podać sourceView i sourceRect lub barButtonItem. Jeśli te informacje nie są znane podczas prezentowania kontrolera alertów, można je podać w metodzie UIPopoverPresentationControllerDelegate -prepareForPopoverPresentation. '

Stephany
źródło
Ten link może ci pomóc.
Nimisha Patel
4
ios 8 i nowszych nie ma instancji UIActionController arkusza działania, musisz ustawić typ jako UIAlertControllerStyleActionSheet .... to może ci pomóc .... chociaż uipopover jest sugerowany dla iPada ....
Arun
Trzeba to zaprezentować jako popover na iPadzie
Totka

Odpowiedzi:

110

Musisz podać widok źródła lub przycisk tuż przed prezentacją menu opcji, ponieważ na iPadzie jest to kontroler UIPopoverPresentationController, jak mówi w twoim błędzie. Oznacza to po prostu, że arkusz akcji wskazuje przycisk, informując użytkownika, skąd się zaczął.

Na przykład, jeśli prezentujesz swoją opcję Menu, dotykając prawego elementu paska nawigacji. Możesz zrobić coś takiego:

optionMenu.popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem

self.presentViewController(optionMenu, animated: true, completion: nil)

lub możesz ustawić taki widok: (potrzebujesz tylko jednego z tych 2)

optionMenu.popoverPresentationController?.sourceView = yourView

self.presentViewController(optionMenu, animated: true, completion: nil)

Pamiętaj również, że jeśli zmienisz UIAlertControllerStyle na Alert zamiast arkusza akcji, nie musisz tego określać. Jestem pewien, że musiałeś to rozgryźć, ale chciałem tylko pomóc każdemu, kto trafi na tę stronę.

MD Singh
źródło
30

Dla mnie ten sam problem. Miałem kontroler UIAlertController, który działał dobrze na telefonie, ale uległ awarii na iPadzie. Arkusz pojawia się po dotknięciu komórki w widoku tabeli.

Dla Swift 3 dodałem 3 linie kodu tuż przed jego prezentacją:

        ...

        sheet.popoverPresentationController?.sourceView = self.view
        sheet.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection()
        sheet.popoverPresentationController?.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)


        self.present(sheet, animated: true, completion: nil)
Zach
źródło
1
To zadziałało w Swift 5.0, ale nie wiem, jak wyświetlić wyskakujące okienko z dołu widoku. Dziękuję Ci!
Florentin Lupascu
@FlorentinLupascu: Po prostu ustaw allowedArrowDirections na UIPopoverArrowDirection.Down i sourceRect = CGRect (x: self.view.bounds.midX, y: self.view.bounds.bottom, width: 0, height: 0)
too
24

Szybki 3

Jak wspomniano wcześniej, należy skonfigurować UIAlertController, aby był prezentowany w określonym punkcie na iPadzie.

Przykład paska nawigacyjnego:

    // 1
    let optionMenu = UIAlertController(title: nil, message: "Choose an option", preferredStyle: .actionSheet)

    // 2
    let deleteAction = UIAlertAction(title: "Option 1", style: .default, handler: {
        (alert: UIAlertAction!) -> Void in
        print("option 1 pressed")
    })
    let saveAction = UIAlertAction(title: "Option 2", style: .default, handler: {
        (alert: UIAlertAction!) -> Void in
        print("option 2 pressed")
    })

    //
    let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: {
        (alert: UIAlertAction!) -> Void in
        print("Cancelled")
    })


    // 4

    optionMenu.addAction(deleteAction)
    optionMenu.addAction(saveAction)
    optionMenu.addAction(cancelAction)

    // 5

    optionMenu.popoverPresentationController?.barButtonItem = self.navigationItem.rightBarButtonItem

    self.present(optionMenu, animated: true) { 
        print("option menu presented")
    }
mourodrigo
źródło
8

Jeśli chcesz przedstawić go w środku bez strzałek [ Swift 3+ ]:

if let popoverController = optionMenu.popoverPresentationController {
        popoverController.sourceView = self.view
        popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
        popoverController.permittedArrowDirections = []
    }
self.present(optionMenu, animated: true, completion: nil)
Mohit Singh
źródło
5

dodaj oświadczenia w następujących terminach przed przedstawieniem.

optionMenu.popoverPresentationController.sourceView = self.view;
optionMenu.popoverPresentationController.sourceRect = 

CGRectMake(0,0,1.0,1.0);


@IBAction func dialog(sender: AnyObject) {
    ...

    optionMenu.popoverPresentationController.sourceView = self.view;
    optionMenu.popoverPresentationController.sourceRect = CGRectMake(0,0,1.0,1.0);

    self.presentViewController(optionMenu, animated: true, completion: nil)
}

będzie działać dobrze.

Jimmy Chou
źródło
Działał doskonale. Jedyną rzeczą jest to, że musisz dodać element lewego paska nawigacyjnego, aby menu podręczne nie wyglądało tak, jakby wychodziło znikąd
Eugene Pavlov
0

Pamiętaj, że możesz również otrzymać ten błąd, jeśli nie powiązałeś widoku źródła w IB z odpowiednią zmienną w swojej aplikacji.

Peter Johnson
źródło
0

musisz to dodać do iPada

alertControler.popoverPresentationController?.sourceView = self.view

Asad Farooq
źródło