Husam
Husam

Reputation: 43

Warning when presenting UIActivityViewController inside a SwiftUI sheet

I use UIActivityViewController to allow my SwiftUI app to share content with other activities:

import Foundation
import SwiftUI

struct ShareSheet : UIViewControllerRepresentable{
    var items: [Any]
    
    func makeUIViewController(context: Context) -> UIActivityViewController {
        let ac = UIActivityViewController(activityItems: items, applicationActivities: nil)
          
        return ac
    }
    
    func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {
        
    }
}

To make it clear, I will use the following simple code:

import SwiftUI

struct ContentView: View {
    @State var showForImageShare: Bool = false
    
    var body: some View {
        VStack {
            Image(systemName: "globe")
                .imageScale(.large)
                .foregroundColor(.accentColor)
            Text("Hello, world!")
                .onTapGesture {
                    showForImageShare.toggle()
                }
        }
        .sheet(isPresented: $showForImageShare){
            let image = "Hello everybody"
            
            ShareSheet(items: [image])
        }
    }
}

I got the following warning in the console:

2022-10-23 23:41:07.692216+0300 Test UIActivityViewController[92164:30374157] [LayoutConstraints] Changing the translatesAutoresizingMaskIntoConstraints property of a UICollectionReusableView that is managed by a UICollectionView is not supported, and will result in incorrect self-sizing. View: <_UIActivityContentFooterView: 0x15cd56340; baseClass = UICollectionReusableView; frame = (16 244.333; 361 52); layer = <CALayer: 0x600001ab8180>>

I use Xcode 14, Deployment Target: 16.0

Could you please help me to find the best way to present UIActivityViewController ?

Upvotes: 0

Views: 494

Answers (2)

Vanamali
Vanamali

Reputation: 11

 struct ActivityView: UIViewControllerRepresentable {
    @Binding var isPresented: Bool
    let activityItems: [Any]
    let applicationActivities: [UIActivity]? = nil

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

    func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
        if isPresented && uiViewController.presentedViewController == nil {
            let activityViewController = UIActivityViewController(
                activityItems: activityItems,
                applicationActivities: applicationActivities
            )
            activityViewController.completionWithItemsHandler = { (_, _, _, _) in
                isPresented = false
            }
            uiViewController.present(activityViewController, animated: true)
        }
    }
}

Upvotes: 0

trianglejerry00
trianglejerry00

Reputation: 614

How about this?

import SwiftUI

struct ContentView: View {
    @State private var isActivityViewPresented = false
    
    var body: some View {
        Button("Share Link") {
            self.isActivityViewPresented = true
        }
        .background(
            ActivityView(
                isPresented: $isActivityViewPresented,
                activityItmes: [URL(string: "https://stackoverflow.com/questions/74174661/warning-when-presenting-uiactivityviewcontroller-inside-a-swiftui-sheet")!]
            )
        )
    }
}

public struct ActivityView: UIViewControllerRepresentable {
    @Binding var isPresented: Bool
    public let activityItmes: [Any]
    public let applicationActivities: [UIActivity]? = nil
    
    public func makeUIViewController(context: Context) -> UIViewController {
        UIViewController()
    }
    
    public func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
        let activityViewController = UIActivityViewController (
            activityItems: activityItmes,
            applicationActivities: applicationActivities
        )
        
        if isPresented && uiViewController.presentedViewController == nil {
            uiViewController.present(activityViewController, animated: true)
        }
        activityViewController.completionWithItemsHandler = { (_, _, _, _) in
            isPresented = false
        }
    }
}

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

Upvotes: 0

Related Questions