Reputation: 851
I am making a share function in my game and I have the code and it works fine on iPhone but when I test it on a iPad, when I tap the share button the app crashes. I am using the following code for the share button
let textToShare = "Check out this website!"
if let myWebsite = NSURL(string: "http://www.apple.com/") {
let objectsToShare = [textToShare, myWebsite]
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
self.view?.window?.rootViewController?.presentViewController(activityVC, animated: true, completion: nil)
}
Upvotes: 21
Views: 10152
Reputation: 1
In iPad SheetVC is not present. So you need to add a source View for a popover controller
@objc private func shareButtonTapped(_ sender: UIButton) {
let image = UIImage(named: "image")
let activityItem: [AnyObject] = [image as AnyObject]
let activityViewController = UIActivityViewController(
activityItems: activityItem as [AnyObject],
applicationActivities: nil
)
if let popoverController = activityViewController.popoverPresentationController {
popoverController.sourceView = sender
popoverController.sourceRect = sender.bounds
}
present(activityViewController, animated: true, completion: nil)
}
Upvotes: -1
Reputation: 11
iOS 16 ready-to-use example based on previous examples, without using deprecated windows
func shareAppIntent() {
let subject = "Share with Friends"
let extraText = "https://apps.apple.com/..."
guard let mainWindowScene = UIApplication.shared.connectedScenes
.compactMap({ $0 as? UIWindowScene })
.first(where: { $0.activationState == .foregroundActive }),
let mainWindow = mainWindowScene.windows.first,
let rootViewController = mainWindow.rootViewController else {
return
}
if let url = URL(string: extraText) {
let activityViewController = UIActivityViewController(activityItems: [subject, url], applicationActivities: nil)
// iPad needs extra context, otherwise it will crash
if UIDevice.current.userInterfaceIdiom == .pad {
activityViewController.popoverPresentationController?.sourceView = mainWindow
activityViewController.popoverPresentationController?.sourceRect = CGRect(x: 0, y: 0, width: 300, height: 350)
activityViewController.popoverPresentationController?.permittedArrowDirections = [.left]
}
rootViewController.present(activityViewController, animated: true, completion: nil)
}
}
Upvotes: -1
Reputation: 555
Building on @Satachito's answer: As the sourceView
you can create an (invisible) CGRect
at the place the popup should point to, and set the arrow in that direction:
let activityVC = UIActivityViewController(activityItems: objectsToShare, applicationActivities: nil)
if UIDevice.current.userInterfaceIdiom == .pad {
activityVC.popoverPresentationController?.sourceView = UIApplication.shared.windows.first
activityVC.popoverPresentationController?.sourceRect = CGRect(x: 0, y: 0, width: 300, height: 350)
activityVC.popoverPresentationController?.permittedArrowDirections = [.left]
}
UIApplication.shared.windows.first?.rootViewController?.present(activityVC, animated: true, completion: nil)
Upvotes: 4
Reputation: 881
The popoverPresentationController
sourceView
needs to be set to current view.
let activityVC = UIActivityViewController(activityItems: [quoteController.attributedString, view.screenShot()], applicationActivities: [])
present(activityVC, animated: true)
activityVC.popoverPresentationController?.sourceView = view
Upvotes: -1
Reputation: 5888
The UIActivityViewController's has non-null popoverPresentationController property when running on iPad. So, try below.
if let wPPC = activityVC.popoverPresentationController {
wPPC.sourceView = some view
// or
wPPC.barButtonItem = some bar button item
}
presentViewController( activityVC, animated: true, completion: nil )
Upvotes: 34