How can create a new "Share View" ( now called "Share sheet" ? ) for iOS 13 ?
In the new features of the iOS 13, we saw how the look (and possibly the way) with which we can share with other applications has changed.
As I read in this article : iOS 13: The Ars Technica review
I want to be able to display this menu with all the share options available in my SwiftUI app:
So, even easier, how can I simply share a link - a text - to another App with Swift 5 using SwiftUI?
What is the new way proposed ? What is the code that I have to write in my View to display this menu of options?
Thank you.
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