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 modalPresentationStyle ของ UIAlertController ที่มีลักษณะนี้คือ UIModalPresentationPopover คุณต้องให้ข้อมูลตำแหน่งสำหรับป๊อปโอเวอร์นี้ผ่าน popoverPresentationController ของตัวควบคุมการแจ้งเตือน คุณต้องระบุ sourceView และ sourceRect หรือ barButtonItem หากไม่ทราบข้อมูลนี้เมื่อคุณนำเสนอตัวควบคุมการแจ้งเตือนคุณสามารถระบุข้อมูลนี้ในเมธอด UIPopoverPresentationControllerDelegate -prepareForPopoverPresentation '


ลิงค์นี้อาจช่วยคุณได้
Nimisha Patel

4
ios 8 ขึ้นไปไม่มีแผ่นการดำเนินการอินสแตนซ์ UIActionController ที่คุณต้องตั้งค่าประเภทเป็น UIAlertControllerStyleActionSheet .... สิ่งนี้อาจช่วยคุณได้ .... แม้ว่าจะแนะนำ uipopover สำหรับ iPad ....
อรุณ

คุณต้องนำเสนอเป็นป๊อป
โอเวอร์

คำตอบ:


110

คุณต้องให้มุมมองแหล่งที่มาหรือปุ่มก่อนที่จะนำเสนอ optionMenu เนื่องจากบน iPad เป็น UIPopoverPresentationController ตามที่ระบุไว้ในข้อผิดพลาดของคุณ นั่นหมายความว่าเอกสารการดำเนินการของคุณชี้ไปที่ปุ่มเพื่อให้ผู้ใช้ทราบว่าเริ่มต้นจากที่ใด

ตัวอย่างเช่นหากคุณกำลังนำเสนอ optionMenu ของคุณโดยแตะที่รายการแถบนำทางด้านขวา คุณสามารถทำสิ่งนี้:

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 แทนแผ่นการดำเนินการคุณไม่จำเป็นต้องระบุสิ่งนี้ ฉันแน่ใจว่าคุณต้องคิดออกแล้ว แต่ฉันแค่อยากช่วยทุกคนที่เจอหน้านี้


31

ปัญหาเดียวกันสำหรับฉัน ฉันมี 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 แต่ฉันไม่รู้วิธีแสดงป๊อปอัปจากด้านล่างของมุมมอง ขอขอบคุณ!
Florentin Lupascu

@FlorentinLupascu: ตั้งค่า per allowArrowDirections เป็น UIPopoverArrowDirection.Down และ sourceRect = CGRect (x: self.view.bounds.midX, y: self.view.bounds.bottom, width: 0, height: 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)
}

มันจะทำงานได้ดี


ทำงานได้อย่างสมบูรณ์แบบ สิ่งเดียวคือคุณต้องเพิ่มรายการแถบนำทางด้านซ้ายดังนั้นเมนูป๊อปโอเวอร์จึงดูเหมือนไม่ได้มาจากที่ไหนเลย
Eugene Pavlov

0

โปรดทราบว่าคุณสามารถรับข้อผิดพลาดนี้ได้หากคุณไม่ได้เชื่อมโยง Sourceview ใน IB กับตัวแปรที่เกี่ยวข้องในแอปของคุณ



โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.