0

I'm trying to present two sheets in SwiftUI. The first sheet (SecondScreen) opens up on the Main Page (tapping the Navigation Tool Bar Icon) and the second sheet is a ShareSheet which should pop up inside the SecondScreen as an option. I have used a Form to build the SecondScreen. In the Simulator and on my device, the ShareSheet doesn't appear. I hope this is just a bug and not something Apple doesn't allow without big UI changes.

I tried to open the ShareSheet, while having the SecondScreen as a .fullScreenCover., instead of .sheet but the button still doesn't react.

Example

import SwiftUI

struct ContentView: View {
    
    @State var showMore: Bool = false
    
    var body: some View {
        NavigationView {
            Text("Main Page")
                .padding()
                .navigationBarTitle("Main Page")
                .toolbar {
                    ToolbarItem(placement: .navigationBarTrailing) {

                    Button(action: {
                        showMore.toggle()
                        
                    }, label: {
                        Image(systemName: "ellipsis.circle")
                    })
                    .sheet(isPresented: $showMore, content: {
                        SecondScreen()
            })
         }
    }
  }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

struct SecondScreen: View {
    var body: some View {
        NavigationView {
           Form {
            Section {
            Button(action: {
                    ShareID (Info: "https://www.google.com")}, label: { Text("Share")
            })
            }

            }
            }
           }
        }
    }

func ShareID(Info: String){
    
let infoU = Info
    
let av = UIActivityViewController(activityItems: [infoU], applicationActivities: nil)
    UIApplication.shared.windows.first?
    .rootViewController?.present(av, animated: true,
    completion: nil)
    
}


Thank you!

Lewis
  • 129
  • 1
  • 8
  • That is because you are trying to present on top of your current sheet. You have to put your share sheet in a uiviewcontroller that attaches to the current sheet – lorem ipsum Aug 18 '21 at 22:41
  • So I have to change the .rootViewController?.present ? – Lewis Aug 18 '21 at 23:00
  • Yes your sheet is currently presented there – lorem ipsum Aug 18 '21 at 23:06
  • I changed the .rootViewController to .ContentView and .self. No changes. Could you be more specific with the suggested change? Thanks a lot. – Lewis Aug 18 '21 at 23:33
  • You can look at this [half modal](https://stackoverflow.com/questions/56700752/swiftui-half-modal/67994666#67994666) sample. Notice how the `presentModalView()` presents. You shouldn't need the iOS 15 stuff so remove the sheet modifiers under `adaptiveSheetPresentationController`. This line `hostPopover.sourceView = super.view` is specifically what I am talking about when I say the new sheet needs to attach to the existing sheet. You would present the `UIActivityViewController` vs the `UIHostingController` I don't have a specific plan for it might take me some time to work out the specifics. – lorem ipsum Aug 18 '21 at 23:44

1 Answers1

1

this is another approach to popup your sheets, even works on my mac:

import SwiftUI

@main
struct TestApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    @State var showMore: Bool = false
    
    var body: some View {
        NavigationView {
            Text("Main Page")
                .padding()
                .navigationBarTitle("Main Page")
                .toolbar {
                    ToolbarItem(placement: .navigationBarTrailing) {
                        Button(action: { showMore.toggle() }) {
                            Image(systemName: "ellipsis.circle")
                        }
                        .sheet(isPresented: $showMore) {
                            SecondScreen()
                        }
                    }
                }
        }
    }
}

struct SecondScreen: View {
    @State var shareIt = false
    @State var info = "https://www.google.com"
    
    var body: some View {
        Button(action: {shareIt = true}) {
            Text("Share")
        }
        .sheet(isPresented: $shareIt, onDismiss: {shareIt = false}) {
            ShareSheet(activityItems: [info as Any])
        }
    }
}

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) { }
}