在 iPad 上将 UIActivityViewController 显示为表单 sheet

Display UIActivityViewController as form sheet on iPad

我试图在不使用弹出窗口(即没有源视图或箭头)的情况下显示共享 sheet。

这是我的代码,从基本的单视图应用程序开始:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func didTapShare(_ sender: UIButton) {
        let activity = UIActivityViewController(activityItems: ["banana"], applicationActivities: nil)
        
        if UIDevice.current.userInterfaceIdiom == .pad {
            activity.modalPresentationStyle = .formSheet
//            activity.preferredContentSize = CGSize(width: 400, height: 400)
        }
        
        present(activity, animated: true, completion: nil)
    }
    
}

这当然是崩溃

"UIPopoverPresentationController (<UIPopoverPresentationController: 0x7fce07507900>) should have a non-nil sourceView or barButtonItem set before the presentation occurs."

但我不希望它看起来像一个弹出窗口,或者有一个箭头 -- 我希望它在屏幕中间显示为一个表单 sheet。

照片应用中的效果如下:

尝试设置以下内容

activity.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection(rawValue: 0)

如果您不想将 UIActivityViewController 显示为弹出窗口,而是显示为 formSheet 或 pageSheet,您可以创建自己的视图控制器,并将 UIActivityViewController 作为其子项。

class ShareSheetController: UIViewController {

    private let activityController: UIActivityViewController

    init(items: [Any]) {
        self.activityController = UIActivityViewController(activityItems: items, applicationActivities: nil)
    
        super.init(nibName: nil, bundle: nil)
    
        modalPresentationStyle = .formSheet // or pageSheet
    }

    required init?(coder: NSCoder) {
        fatalError()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
    
        addChild(activityController)
        view.addSubview(activityController.view)

        activityController.view.translatesAutoresizingMaskIntoConstraints = false
    
        NSLayoutConstraint.activate([
            activityController.view.topAnchor.constraint(equalTo: view.topAnchor),
            activityController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            activityController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            activityController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor)
        ])
    }

}

然后您可以像显示任何其他视图控制器一样显示 ShareSheetController

let shareController = ShareSheetController(items: ["some_text"])
present(shareController, animated: true)