You can just create its own UIViewController
struct CustomModalParent: View {
@State var presentShareSheet = false
var body: some View {
VStack{
Button(presentShareSheet ? "dismiss share sheet" : "present share sheet", action: {
presentShareSheet.toggle()
}).adaptiveShareSheet(isPresented: $presentShareSheet, activityItems: ["from view modifier"]) { activityType, completed, returnedItems, error in
//Your code
//This is needed here to update the Binding variable when closing isn't detected otherwise
presentShareSheet = false
}
}
}
}
///View extention for the ShareSheet
extension View {
typealias Callback = (_ activityType: UIActivity.ActivityType?, _ completed: Bool, _ returnedItems: [Any]?, _ error: Error?) -> Void
func adaptiveShareSheet(isPresented: Binding<Bool>, swipeToDismiss: Bool = true, transitionStyle: UIModalTransitionStyle = .coverVertical, activityItems: [Any] = ["Some Text"], applicationActivities: [UIActivity]? = nil, excludedActivityTypes: [UIActivity.ActivityType]? = nil,callback: Callback? = nil) -> some View {
ZStack{
self
CustomShareSheet_UI(isPresented: isPresented, swipeToDismiss: swipeToDismiss, transitionStyle: transitionStyle, activityItems: activityItems, applicationActivities: applicationActivities,callback: callback).frame(width: 0, height: 0, alignment: .center)
}
}
}
///Interface for UIActivityViewController with SwiftUI
struct CustomShareSheet_UI: UIViewControllerRepresentable {
//Share
typealias Callback = (_ activityType: UIActivity.ActivityType?, _ completed: Bool, _ returnedItems: [Any]?, _ error: Error?) -> Void
let activityItems: [Any]
let applicationActivities: [UIActivity]?
let excludedActivityTypes: [UIActivity.ActivityType]?
let callback: Callback?
//Presentattion
@Binding var isPresented: Bool
//Adaptive
let swipeToDismiss: Bool
let transitionStyle: UIModalTransitionStyle
//MARK: init
init(isPresented: Binding<Bool>, swipeToDismiss: Bool = true, transitionStyle: UIModalTransitionStyle = .coverVertical, activityItems: [Any] = ["Some Text"], applicationActivities: [UIActivity]? = nil, excludedActivityTypes: [UIActivity.ActivityType]? = nil,callback: Callback? = nil) {
self.swipeToDismiss = swipeToDismiss
self.transitionStyle = transitionStyle
//Presentation
self._isPresented = isPresented
//Share
self.activityItems = activityItems
self.applicationActivities = applicationActivities
self.excludedActivityTypes = excludedActivityTypes
self.callback = callback
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIViewController(context: Context) -> CustomShareSheetViewController{
let vc = CustomShareSheetViewController(coordinator: context.coordinator, swipeToDismiss: swipeToDismiss, transitionStyle: transitionStyle, activityItems: activityItems, applicationActivities: applicationActivities,callback: callback)
return vc
}
func updateUIViewController(_ uiViewController: CustomShareSheetViewController, context: Context) {
if isPresented{
uiViewController.presentModalView()
}else{
uiViewController.dismissModalView()
}
if uiViewController.presentedViewController == nil && isPresented == true{
isPresented = false
}
}
class Coordinator: NSObject, UIAdaptivePresentationControllerDelegate {
var parent: CustomShareSheet_UI
init(_ parent: CustomShareSheet_UI) {
self.parent = parent
}
//Adjust the variable when the user dismisses with a swipe
func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
if parent.isPresented{
parent.isPresented = false
}
}
}
}
class CustomShareSheetViewController: UIViewController {
//MARK: Share
typealias Callback = (_ activityType: UIActivity.ActivityType?, _ completed: Bool, _ returnedItems: [Any]?, _ error: Error?) -> Void
let activityItems: [Any]
let applicationActivities: [UIActivity]?
let excludedActivityTypes: [UIActivity.ActivityType]?
let callback: Callback?
//MARK: Coordinator
let coordinator: CustomShareSheet_UI.Coordinator
//MARK: Adaptive Options
let swipeToDismiss: Bool
let transitionStyle: UIModalTransitionStyle
init(coordinator: CustomShareSheet_UI.Coordinator, swipeToDismiss: Bool = true, transitionStyle: UIModalTransitionStyle = .coverVertical, activityItems: [Any] = ["Some Text"], applicationActivities: [UIActivity]? = nil, excludedActivityTypes: [UIActivity.ActivityType]? = nil,callback: Callback? = nil) {
//Coordinator
self.coordinator = coordinator
//Adaptive
self.swipeToDismiss = swipeToDismiss
self.transitionStyle = transitionStyle
//Share
self.activityItems = activityItems
self.applicationActivities = applicationActivities
self.excludedActivityTypes = excludedActivityTypes
self.callback = callback
super.init(nibName: nil, bundle: .main)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func dismissModalView(){
dismiss(animated: true, completion: nil)
}
func presentModalView(){
print(#function)
let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: applicationActivities)
controller.excludedActivityTypes = excludedActivityTypes
controller.completionWithItemsHandler = callback
controller.modalPresentationStyle = .popover
controller.presentationController?.delegate = coordinator as UIAdaptivePresentationControllerDelegate
controller.isModalInPresentation = !swipeToDismiss
controller.modalTransitionStyle = UIModalTransitionStyle.coverVertical
if presentedViewController == nil{
present(controller, animated: true, completion: nil)
}
}
}