Sharelink dismisses Parent View

Hello Folks,

what's causing the "smart" dismiss after shareLink? this only happens when saving the photos.

  • view -> opens a popover -> sharelink -> save to photo -> Allow photo Access -> ✅
  • view -> opens a popover -> sharelink -> save to photo -> [Observe popover dismisses ❌] popover should stay open

Remember to add INFOPLIST_KEY_NSPhotoLibraryAddUsageDescription = save to album in project settings

import SwiftUI

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


struct ContentView: View {
    @State private var showingSharePopover = false

    @State private var urlToShare: URL = Bundle.main.url(forResource: "BigBuckBunny", withExtension: "mp4") ?? URL(string: "https://www.example.com")!

    var body: some View {
        VStack {
            Button {
                showingSharePopover = true
            } label: {
                Label("Show Share Options", systemImage: "square.and.arrow.up")
                    .font(.title2)
                    .padding(.vertical, 10)
                    .padding(.horizontal, 20)
            }
            .buttonStyle(.borderedProminent)
            .tint(.indigo)
            .controlSize(.large)
            .shadow(radius: 5)
            .popover(isPresented: $showingSharePopover, attachmentAnchor: .point(.center)) {
                ShareLinkPopoverView(url: urlToShare)
            }
        }
        .padding()
    }
}

struct ShareLinkPopoverView: View {
    let url: URL

    var body: some View {
        VStack(spacing: 20) {
            ShareLink(item: url) {
                Label("Share Now", systemImage: "square.and.arrow.up")
                    .font(.headline)
                    .padding(.vertical, 8)
                    .padding(.horizontal, 15)
            }
            .interactiveDismissDisabled()
            .buttonStyle(.borderedProminent)
            .tint(.green)
            .controlSize(.regular)
        }
        .padding(20)
        .presentationCompactAdaptation(.popover)
    }
}
Answered by John-Doe in 854904022

Here's a sharelinkDropin for those who needs it. The following would not dismiss the presenting view when save to photos.


//
//  SharelinkDropin.swift
//

import SwiftUI

struct SharelinkDropin<Label: View>: View {
    
    let item: URL
    
    @ViewBuilder
    let label: Label
    
    @State var isPresented: Bool = false
    
    var body: some View {
        Button {
            self.isPresented.toggle()
        } label: {
            self.label
        }
        .sheet(isPresented: self.$isPresented, content: {
            ActivityViewController(activityItems: [self.item])
        })

    }
}

fileprivate
struct ActivityViewController: UIViewControllerRepresentable {

    var activityItems: [Any]
    var applicationActivities: [UIActivity]? = nil

    func makeUIViewController(context: UIViewControllerRepresentableContext<ActivityViewController>) -> UIActivityViewController {
        let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: applicationActivities)
        return controller
    }

    func updateUIViewController(_ uiViewController: UIActivityViewController, context: UIViewControllerRepresentableContext<ActivityViewController>) {}

}


#Preview {
    SharelinkDropin(item: URL.placeholderIcon, label: {
        Text("Share")
    })
}

x-posted on reddit: https://www.reddit.com/r/SwiftUI/comments/1mtm9cn/bug_or_feature_sharelink_smart_dismiss_presenting/?

This issue occurs when using a sheet, rather than the popover style too. Running a quick test, using UIActivityViewController seems like a workaround but I understand you would prefer to use the ShareLink.

Accepted Answer

Here's a sharelinkDropin for those who needs it. The following would not dismiss the presenting view when save to photos.


//
//  SharelinkDropin.swift
//

import SwiftUI

struct SharelinkDropin<Label: View>: View {
    
    let item: URL
    
    @ViewBuilder
    let label: Label
    
    @State var isPresented: Bool = false
    
    var body: some View {
        Button {
            self.isPresented.toggle()
        } label: {
            self.label
        }
        .sheet(isPresented: self.$isPresented, content: {
            ActivityViewController(activityItems: [self.item])
        })

    }
}

fileprivate
struct ActivityViewController: UIViewControllerRepresentable {

    var activityItems: [Any]
    var applicationActivities: [UIActivity]? = nil

    func makeUIViewController(context: UIViewControllerRepresentableContext<ActivityViewController>) -> UIActivityViewController {
        let controller = UIActivityViewController(activityItems: activityItems, applicationActivities: applicationActivities)
        return controller
    }

    func updateUIViewController(_ uiViewController: UIActivityViewController, context: UIViewControllerRepresentableContext<ActivityViewController>) {}

}


#Preview {
    SharelinkDropin(item: URL.placeholderIcon, label: {
        Text("Share")
    })
}
Sharelink dismisses Parent View
 
 
Q