'Display UIActivityViewController as form sheet on iPad
I'm trying to display a share sheet without using a popover, ie no source view, or arrow.
Here's my code, starting from a base, single view app:
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)
}
}
This is of course crashing
"UIPopoverPresentationController (<UIPopoverPresentationController: 0x7fce07507900>) should have a non-nil sourceView or barButtonItem set before the presentation occurs."
But I don't want it to look like a popup, or have an arrow -- I want it to appear as a form sheet, in the middle of the screen.
Here's how it look in the Photos app:
Solution 1:[1]
If you don't want to display UIActivityViewController
as popover but rather as formSheet or pageSheet, you can just create your own view controller with UIActivityViewController
as its child.
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)
])
}
}
Then you can present the ShareSheetController
just like any other view controller.
let shareController = ShareSheetController(items: ["some_text"])
present(shareController, animated: true)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | vinzee |