web-dev-qa-db-ja.com

iPadでアクションシートを表示する方法

現在のコードを使用しているときにiPadでUIActionsheetを表示するには、次のエラーが表示されます。

アプリケーションは、スタイルUIAlertControllerUIAlertControllerStyleActionSheet<UIAlertController: 0x7f9ec624af70>)を提示しました。このスタイルのmodalPresentationStyleUIAlertControllerUIModalPresentationPopoverです。アラートコントローラのpopoverPresentationControllerを介して、このポップオーバーの位置情報を提供する必要があります。 sourceViewsourceRectまたはbarButtonItemのいずれかを指定する必要があります。アラートコントローラを提示したときにこの情報がわからない場合は、UIPopoverPresentationControllerDelegateメソッド-prepareForPopoverPresentationで提供できます。

これは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)

私はいくつかの同様の問題に遭遇しました、解決策はこれでした:

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

しかし、おそらく私のActionSheetの送信者がUItableviewCellにあるため、うまくいきませんでした。

AlertControllerのSourceviewをtableViewのCellに設定するのに疲れましたが、正しく配置されておらず、部分的に表示されることがあります。これが私が試したものです。

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

この問題を解決するにはどうすればよいですか?

9
remy boys

以下に示すサンプルコードは、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)
9

IPadでActionSheetを表示したい場合は、popoverPresentationControllerを使用して表示し、iPadではアクションシートのキャンセルスタイルボタンを表示しません。このコードを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)
}

幸運を!

3
Gourav kumar

Swift 4.1ソリューション:-

  1. MAK拡張ファイル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. 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. UIButton Click for iPhone/iPadから使用してください:-
   @objc func btnPicImageTaped(btn:UIButton){
        print("it will work for both iPhone /ipad")
        Common.showActionSheet(vc: self,sender: btn)
}
3

PresentViewControllerの前に次の2行を追加します。 (Swift 3.2

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

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
    }

}
0
Talha Rasool