Details
- Xcode 11.4.1 (11E503a), Swift 5.2
Solution
TopViewController solution
extension UIApplication {
class var topViewController: UIViewController? { return getTopViewController() }
private class func getTopViewController(base: UIViewController? = UIApplication.shared.keyWindow?.rootViewController) -> UIViewController? {
if let nav = base as? UINavigationController { return getTopViewController(base: nav.visibleViewController) }
if let tab = base as? UITabBarController {
if let selected = tab.selectedViewController { return getTopViewController(base: selected) }
}
if let presented = base?.presentedViewController { return getTopViewController(base: presented) }
return base
}
private class func _share(_ data: [Any],
applicationActivities: [UIActivity]?,
setupViewControllerCompletion: ((UIActivityViewController) -> Void)?) {
let activityViewController = UIActivityViewController(activityItems: data, applicationActivities: nil)
setupViewControllerCompletion?(activityViewController)
UIApplication.topViewController?.present(activityViewController, animated: true, completion: nil)
}
class func share(_ data: Any...,
applicationActivities: [UIActivity]? = nil,
setupViewControllerCompletion: ((UIActivityViewController) -> Void)? = nil) {
_share(data, applicationActivities: applicationActivities, setupViewControllerCompletion: setupViewControllerCompletion)
}
class func share(_ data: [Any],
applicationActivities: [UIActivity]? = nil,
setupViewControllerCompletion: ((UIActivityViewController) -> Void)? = nil) {
_share(data, applicationActivities: applicationActivities, setupViewControllerCompletion: setupViewControllerCompletion)
}
}
Usage
UIApplication.share("Text to share")
let data = ["Text, Image and url", image, url] as [Any]
UIApplication.share(data)
Full sample
Do not forget to add the solution code here (look above)
import UIKit
class ViewController: UIViewController {
private weak var imageView: UIImageView?
override func viewDidLoad() {
super.viewDidLoad()
var button = UIButton(frame: CGRect(x: 50, y: 50, width: 200, height: 40))
button.setTitle("Share text", for: .normal)
button.addTarget(self, action: #selector(shareButtonTapped), for: .touchUpInside)
button.setTitleColor(.blue, for: .normal)
view.addSubview(button)
button = UIButton(frame: CGRect(x: 50, y: 80, width: 200, height: 40))
button.setTitle("Share text & image", for: .normal)
button.addTarget(self, action: #selector(shareCombinedData), for: .touchUpInside)
button.setTitleColor(.blue, for: .normal)
view.addSubview(button)
let imageView = UIImageView(frame: CGRect(x: 50, y: 120, width: 200, height: 200))
imageView.image = UIImage(named: "image")
imageView.isUserInteractionEnabled = true
imageView.contentMode = .scaleAspectFill
imageView.clipsToBounds = true
imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(imageViewTapped)))
view.addSubview(imageView)
self.imageView = imageView
}
@objc func shareButtonTapped() { UIApplication.share("Text to share") }
@objc func imageViewTapped() {
guard let image = imageView?.image else { return }
UIApplication.share(image)
}
@objc func shareCombinedData() {
guard let image = imageView?.image, let url = URL(string: "http://google.com") else { return }
let data = ["Text, Image and url", image, url] as [Any]
UIApplication.share(data)
}
}
Sample result
