如何从显示的 sheet 中打开分享 Sheet

How to open Share Sheet from presented sheet

按照几个教程 (Medium for example),您可以像这样打开共享 sheet:

Button(action: {
                    
    let url = URL(string: "https://apple.com")
    let av = UIActivityViewController(activityItems: [url!], applicationActivities: nil)
                    
    UIApplication.shared.windows.first?.rootViewController?.present(av, animated: true, completion: nil)
}) {
  Text("Share Me")
}

但是,这在呈现的 sheet 中不起作用。

BaseView,带有工作共享示例 sheet 和打开代码 Sheet:

struct BaseView: View {
   
   ...
   @State var isSheetViewShowing = false
   ...

   var body: some View {

       // Open sheet view where share sheet does not work.
       Button(action: {
            isSheetViewShowing.toggle()
      }) {
        Text("Show sheet view")
      }

       Text("")
          .frame(width: 0, height: 0)
          .sheet(isPresented: $isSheetViewShowing) {
              SheetView(showSheetView: $isSheetViewShowing)
          }

      // Below share Sheet works!
      Button(action: {
                    
         let url = URL(string: "https://apple.com")
         let av = UIActivityViewController(activityItems: [url!], applicationActivities: nil)
                    
         UIApplication.shared.windows.first?.rootViewController?.present(av, animated: true, completion: nil)
      }) {
        Text("Share Me")
      }
   }

}

打开了Sheet视图,其中相同的代码不起作用:

struct SheetView: View {
  
   ...
   @Binding var showSheetView: Bool
   ...

   var body: some View {
       

      // Below share Sheet does not work anymore!
      Button(action: {
                    
         let url = URL(string: "https://apple.com")
         let av = UIActivityViewController(activityItems: [url!], applicationActivities: nil)
                    
         UIApplication.shared.windows.first?.rootViewController?.present(av, animated: true, completion: nil)
      }) {
        Text("Share Me")
      }
   }
}

如何在 sheet 视图中显示共享 sheet?是否必须将共享内容的意图传递给 BaseView(和/或 SheetView 是否必须关闭)然后从那里调用共享 sheet? (我希望直接从 SheetView 获得解决方案)

问题在于尝试从根控制器显示第二个 sheet。它已经附加了一个,因此拒绝另一个(在本例中为 Activity)。

解决方案是使用自己的控制器,将我们的 sheet 作为 activity.

的演示者打开

这是一个简单的演示。测试 Xcode 13 / iOS 15.

struct SheetView: View {

   @Binding var showSheetView: Bool
    @State private var isShare = false
   var body: some View {


      // Below share Sheet - now works!
      Button(action: {
            isShare = true    // present activity
      }) {
        Text("Share Me")
      }
      .background(SharingViewController(isPresenting: $isShare) {
         let url = URL(string: "https://apple.com")
         let av = UIActivityViewController(activityItems: [url!], applicationActivities: nil)
         av.completionWithItemsHandler = { _, _, _, _ in
                isShare = false // required for re-open !!!
            }
            return av
        })
   }
}

struct SharingViewController: UIViewControllerRepresentable {
    @Binding var isPresenting: Bool
    var content: () -> UIViewController

    func makeUIViewController(context: Context) -> UIViewController {
        UIViewController()
    }

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
        if isPresenting {
            uiViewController.present(content(), animated: true, completion: nil)
        }
    }
}