ActionSheet не працює iPad


86

Я використовую ActionSheet у своєму додатку. На моєму iPhone це працює, але на симуляторі iPad - ні.

це мій код:

@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)
}

І моя помилка:

Завершення роботи програми через невловлюваний виняток "NSGenericException", причина: "У вашій програмі представлений UIAlertController () стилю UIAlertControllerStyleActionSheet. МодальнийPresentationStyle UIAlertController з цим стилем - UIModalPresentationPopover. Ви повинні надати інформацію про місцезнаходження цього поповера через контролер оповіщення popoverPresentationController. Ви повинні надати або sourceView та sourceRect, або barButtonItem. Якщо ця інформація невідома, коли ви представляєте контролер попереджень, ви можете надати її в методі UIPopoverPresentationControllerDelegate -prepareForPopoverPresentation. '


Це посилання може вам допомогти.
Німіша Патель

4
ios 8 і вище немає екземпляра дії. Екземпляр UIActionController u потрібно встановити тип як UIAlertControllerStyleActionSheet .... це може вам допомогти .... хоча uipopover пропонується для iPad ....
Arun

Ви повинні представити це як поповер на iPad
Тотка

Відповіді:


110

Вам потрібно надати подання джерела або кнопку безпосередньо перед тим, як представити optionMenu, оскільки на iPad це UIPopoverPresentationController, як це пише у вашій помилці. Це просто означає, що ваш аркуш дій вказує на кнопку, що повідомляє користувачеві, з чого це почалося.

Наприклад, якщо ви представляєте свій параметр Menu, натискаючи правий елемент панелі навігації. Ви можете зробити щось подібне:

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

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

або ви можете встановити такий вигляд: (Вам просто потрібен один із цих 2)

optionMenu.popoverPresentationController?.sourceView = yourView

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

Також майте на увазі, що якщо ви зміните UIAlertControllerStyle на Alert замість аркуша дій, вам не потрібно буде це вказувати. Я впевнений, ви напевно це зрозуміли, але я просто хотів допомогти кожному, хто потрапляє на цю сторінку.


30

Та сама проблема для мене. У мене був UIAlertController, який чудово працював на телефоні, але аварійно працював на iPad. Аркуш спливає, коли клітинка натискається з подання таблиці.

Для Swift 3 я додав 3 рядки коду безпосередньо перед тим, як представити його:

        ...

        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)

1
Це працювало для мене в Swift 5.0, але я не знаю, як показати спливаюче вікно знизу подання. Дякую!
Флорентін

@FlorentinLupascu: Просто встановіть permittedArrowDirections на UIPopoverArrowDirection.Down і sourceRect = CGRect (x: self.view.bounds.midX, y: self.view.bounds.bottom, ширина: 0, висота: 0)
теж

24

Стрімкий 3

Як вже було сказано раніше, вам слід налаштувати UIAlertController для представлення в певній точці на iPAD.

Приклад для панелі навігації:

    // 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")
    }

8

Якщо ви хочете представити його в центрі без стрілок [ 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)

5

до подання додайте твердження в наступних термінах.

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

це буде працювати добре.


Працював ідеально. Єдине, що вам потрібно додати елемент лівої панелі навігації, щоб меню поповер не здавалося, що воно з’являється з нізвідки
Євген Павлов,

0

Тільки зауважте, що ви також можете отримати цю помилку, якщо не пов’язали sourceview у IB із відповідною змінною у вашому додатку.



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.