简体   繁体   English

如何在 iPad 中显示 Actionsheet

[英]How to show Actionsheet in iPad

How can I show a UIActionsheet in iPad when I'm using my current code its giving me this error:当我使用我当前的代码时,如何在 iPad 中显示UIActionsheet给我这个错误:

Your application has presented a UIAlertController ( <UIAlertController: 0x7f9ec624af70> ) of style UIAlertControllerStyleActionSheet .您的应用程序已经呈现出UIAlertController<UIAlertController: 0x7f9ec624af70>风格的UIAlertControllerStyleActionSheet The modalPresentationStyle of a UIAlertController with this style is UIModalPresentationPopover .modalPresentationStyle一个的UIAlertController这种风格是UIModalPresentationPopover You must provide location information for this popover through the alert controller's popoverPresentationController .您必须通过警报控制器的popoverPresentationController提供此弹出popoverPresentationController位置信息。 You must provide either a sourceView and sourceRect or a barButtonItem .您必须提供sourceViewsourceRectbarButtonItem If this information is not known when you present the alert controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation .如果在您呈现警报控制器时不知道此信息,您可以在UIPopoverPresentationControllerDelegate方法-prepareForPopoverPresentation提供它。

which is working totally fine in an iPhone :这在 iPhone 中完全正常:

let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
let reminderAction = UIAlertAction(title: "Reminder", style: .Default, handler: {
                (alert: UIAlertAction!) -> Void in }
optionMenu.addAction(reminderAction)
self.presentViewController(optionMenu, animated: true, completion: nil)

I came across some similar problems, the solution was this:我遇到了一些类似的问题,解决方案是这样的:

let optionMenu = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
optionMenu.popoverPresentationController?.sourceView = self.view
optionMenu.popoverPresentationController?.sourceRect = self.view.bounds

but it didnt worked for me maybe because my ActionSheet's Sender is on a UItableviewCell.但它对我不起作用,可能是因为我的 ActionSheet 的发件人在 UItableviewCell 上。

I tired to set AlertController's Sourceview to tableView's Cell but its not correctly placed and sometime its partially visible this is what I tried:我厌倦了将 AlertController 的 Sourceview 设置为 tableView 的 Cell 但它没有正确放置,有时它部分可见,这就是我尝试的:

optionMenu.popoverPresentationController?.sourceView = currentCell.contentView
optionMenu.popoverPresentationController?.sourceRect = currentCell.contentView.bounds

Any clue how can I fix this problem?任何线索我该如何解决这个问题?

The sample code given below works both on iPhone and iPad.下面给出的示例代码适用于 iPhone 和 iPad。

 guard let viewRect = sender as? UIView else {
            return
        }

    let cameraSettingsAlert = UIAlertController(title: NSLocalizedString("Please choose a course", comment: ""), message: NSLocalizedString("", comment: ""), preferredStyle: .ActionSheet)
    cameraSettingsAlert.modalPresentationStyle = .Popover

    let photoResolutionAction = UIAlertAction(title: NSLocalizedString("Photo Resolution", comment: ""), style: .Default) { action in

    }
    let cameraOrientationAction = UIAlertAction(title: NSLocalizedString("Camera Orientation", comment: ""), style: .Default) { action in

    }
    let flashModeAction = UIAlertAction(title: NSLocalizedString("Flash Mode", comment: ""), style: .Default) { action in

    }
    let timeStampOnPhotoAction = UIAlertAction(title: NSLocalizedString("Time Stamp on Photo", comment: ""), style: .Default) { action in

    }
    let cancel = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .Cancel) { action in

    }
    cameraSettingsAlert.addAction(cancel)
    cameraSettingsAlert.addAction(cameraOrientationAction)
    cameraSettingsAlert.addAction(flashModeAction)
    cameraSettingsAlert.addAction(timeStampOnPhotoAction)
    cameraSettingsAlert.addAction(photoResolutionAction)

    if let presenter = cameraSettingsAlert.popoverPresentationController {
        presenter.sourceView = viewRect;
        presenter.sourceRect = viewRect.bounds;
    }
    presentViewController(cameraSettingsAlert, animated: true, completion: nil)

If you want to show any ActionSheet on iPad so their use popoverPresentationController to show and at iPad don't show the cancel style button of action sheet.如果你想在 iPad 上显示任何 ActionSheet,那么他们使用 popoverPresentationController 来显示并且在 iPad 上不显示操作表的取消样式按钮。 Use this code in Swift 3:在 Swift 3 中使用此代码:

  @IBAction func ActionSheetShow(_ sender: UIButton) {

  let actionSheet = UIAlertController(title: "Choose any option", message: "choose as you like here!", preferredStyle: .actionSheet)

    actionSheet.addAction(UIAlertAction(title: "Click1", style: .cancel, handler: {
    action in
        print("first button")
    }))
    actionSheet.addAction(UIAlertAction(title: "Click2", style: .default, handler: {
        action in
        print("second button")
    }))
    actionSheet.addAction(UIAlertAction(title: "Click3", style: .destructive, handler: {
        action in
        print("third button")
    }))
    actionSheet.popoverPresentationController?.sourceView = self.view
    actionSheet.popoverPresentationController?.sourceRect = sender.frame
    present(actionSheet, animated: true, completion: nil)
}

Good Luck!祝你好运!

Swift 4.1 Solution:- Swift 4.1 解决方案:-

  1. MAK Eextension FILE UIDEviceExtension.swift and with below code :- MAK Eextension FILE UIDEviceExtension.swift 和以下代码:-
import Foundation
import UIKit
public extension UIDevice {

    public class var isPhone: Bool {
        return UIDevice.current.userInterfaceIdiom == .phone
    }

    public class var isPad: Bool {
        return UIDevice.current.userInterfaceIdiom == .pad
    }

    public class var isTV: Bool {
        return UIDevice.current.userInterfaceIdiom == .tv
    }

    public class var isCarPlay: Bool {
        return UIDevice.current.userInterfaceIdiom == .carPlay
    }

}
  1. Call your action Sheet on UIViewcontroller By this Separate common method :-通过这种单独的通用方法在 UIViewcontroller 上调用您的操作表:-
import Foundation
import UIKit
class Common: NSObject{
       public class func showActionSheet(vc: UIViewController,sender:UIButton? = nil) {

                let actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)

                actionSheet.addAction(UIAlertAction(title: "Camera", style: .default, handler: { (alert:UIAlertAction!) -> Void in
                    //self.camera()
                }))

                actionSheet.addAction(UIAlertAction(title: "Gallery", style: .default, handler: { (alert:UIAlertAction!) -> Void in
                    //self.photoLibrary()
                }))

                actionSheet.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))

                //if iPhone
                if UIDevice.isPhone {
                    vc.present(actionSheet, animated: true, completion: nil)
                }
                else {
                    //In iPad Change Rect to position Popover
                    if let btn = sender{
                        actionSheet.popoverPresentationController?.sourceRect = btn.frame
                        actionSheet.popoverPresentationController?.sourceView = vc.view

                    }
                    vc.present(actionSheet, animated: true, completion: nil)
                }

            }
    }
  1. Use it from your UIButton Click for iPhone/iPad both :-从你的 UIButton Click for iPhone/iPad 使用它:-
   @objc func btnPicImageTaped(btn:UIButton){
        print("it will work for both iPhone /ipad")
        Common.showActionSheet(vc: self,sender: btn)
}

Add Following two lines before presentViewController.在presentViewController之前添加以下两行。 ( Swift 3.2 ) (斯威夫特 3.2 )

 optionMenu.popoverPresentationController?.sourceView = self.view
 optionMenu.popoverPresentationController?.sourceRect = (sender as AnyObject).frame
 present(optionMenu, animated: true, completion: nil)

Updated for swift 5更新为 swift 5

extension UIDevice {

    class var isPhone: Bool {
        return UIDevice.current.userInterfaceIdiom == .phone
    }

     class var isPad: Bool {
        return UIDevice.current.userInterfaceIdiom == .pad
    }

     class var isTV: Bool {
        return UIDevice.current.userInterfaceIdiom == .tv
    }

     class var isCarPlay: Bool {
        return UIDevice.current.userInterfaceIdiom == .carPlay
    }

}

You can take sourceView & sourceRect from sender:您可以从发件人处获取 sourceView 和 sourceRect:

@IBAction func btMenuPressed(_ sender: Any) {
    let Sender = sender as? UIButton
    let actSheet = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet)
    actSheet.addAction(UIAlertAction(title: "settings", style: .default) { _ in self.doSettings() })
    ...
    ...
    actSheet.popoverPresentationController?.sourceView = Sender!.superview!    
    actSheet.popoverPresentationController?.sourceRect = Sender!.frame
    resent(actSheet, animated: true)
}

Swift 5+ solution Very smooth and easy just call this function and you will easy solve your problem Swift 5+ 解决方案非常流畅和简单只需调用此函数,您就可以轻松解决您的问题

let IPAD = UIDevice.current.userInterfaceIdiom == .pad


//Mark:- Choose Action Sheet Methods
func actionSheet() {
    var actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertController.Style.actionSheet)

    actionSheet.view.tintColor = UIColor.black

    let button1 = UIAlertAction(title: "Button 1".localizableString(language: Defaults.selectedLanguageCode), style: .default, handler: {
        (alert: UIAlertAction!) -> Void in

    })
    let button2 = UIAlertAction(title: "Button 2".localizableString(language: Defaults.selectedLanguageCode), style: .default, handler: {
        (alert: UIAlertAction!) -> Void in

    })
    let cancelAction = UIAlertAction(title: "Cancel".localizableString(language: Defaults.selectedLanguageCode), style: .cancel, handler: {
        (alert: UIAlertAction!) -> Void in
    })


    if IPAD {
        //In iPad Change Rect to position Popover
        actionSheet = UIAlertController(title: nil, message: nil, preferredStyle: UIAlertController.Style.alert)
    }
    actionSheet.addAction(button1)
    actionSheet.addAction(button2)
    actionSheet.addAction(cancelAction)
    print("Action Sheet Open")

    self.present(actionSheet, animated: true, completion: nil)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM