It works in much the same way as in UIKit, but you'll have to use
.sheet(isPresented:content:)
to make the view appear.
What you need is the
UIActivityViewController
, which means you'll have to create a SwiftUI
UIViewControllerRepresentable
view for that. In this case it's fairly straightforward, since you're not modifying the content or maintaining any state, you're effectively wrapping the initializer. This version works for me:
struct ShareSheet: UIViewControllerRepresentable {
typealias Callback = (_ activityType: UIActivity.ActivityType?, _ completed: Bool, _ returnedItems: [Any]?, _ error: Error?) -> Void
let activityItems: [Any]
let applicationActivities: [UIActivity]? = nil
let excludedActivityTypes: [UIActivity.ActivityType]? = nil
let callback: Callback? = nil
func makeUIViewController(context: Context) -> UIActivityViewController {
let controller = UIActivityViewController(
activityItems: activityItems,
applicationActivities: applicationActivities)
controller.excludedActivityTypes = excludedActivityTypes
controller.completionWithItemsHandler = callback
return controller
}
func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {
// nothing to do here
}
}
In your other view, you want this to appear modally, so you use the
.sheet()
method to do so, along with an
isPresented
state variable, like so:
struct ContentView: View {
@State private var showShareSheet = false
var body: some View {
VStack(spacing: 20) {
Text("Hello World")
Button(action: {
self.showShareSheet = true
}) {
Text("Share Me").bold()
}
}
.sheet(isPresented: $showShareSheet) {
ShareSheet(activityItems: ["Hello World"])
}
}
}
One inconvenience is that it always appears full-size for me, and I'm not sure if there's something I'm supposed to do to get the half-covered appearance that occurs in most apps.
Hope this helps. I've posted a sample project on Github here: https://github.com/AlanQuatermain/SwiftUIShareSheetDemo