ios – Swiftui: How to snapshot a view then share?

[ad_1]

I found this code for taking a snapshot of a view in SwiftUI, and also found this gist for how to bring up UIActivityController in SwiftUI. It works ok but the biggest issue I am having is when you tap share the UIActivityController is blank, if you tap share again it will work as expected but I can’t figure out why it doesn’t work the first time? If I change to a static image or text to share it works as expected? Any thoughts?

struct ShareHomeView: View {
    
    @Environment(\.sizeCategory) var sizeCategory
    
    @State private var isShowingLibrary = false
  
    @Binding var workoutImage: UIImage
    
    @State private var shareCardAsImage: UIImage? = nil
    @State private var showShareSheet = false
    
    var shareCard: some View {
        ZStack {
            VStack {
                Spacer()
                LinearGradient(
                    gradient: Gradient(colors: [.black, .athlyticButtonColor]),
                    startPoint: .topLeading,
                    endPoint: .bottomTrailing
                )
                    .cornerRadius(10.0)
                    .padding(.horizontal)
                Spacer()
            }
            OverviewView()
                .padding(.horizontal)
            VStack {
                HStack {
                    HStack(alignment: .center) {
                        Image("Logo")
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                            .frame(height: 40)
                            .padding(.leading)
                        VStack(alignment: .leading, spacing: 3) {
                            Text("App Name")
                                .foregroundColor(.white)
                                .font(.headline)
                                .fontWeight(.bold)
                            Text("Wed 30 Mar 22")
                                .foregroundColor(.white)
                                .font(.headline)
                        }
                    }
                    Spacer()
                }
                .padding([.leading, .top])
                Spacer()
            }
            
        } //End of ZStack
        .frame(height: 350)
        .background(Color.clear)
    }
    
    var body: some View {
        NavigationView {
            VStack {
                HStack {
                    Spacer()
                    Button {
                        isShowingLibrary.toggle()
                    } label: {
                        Image(systemName: "photo")
                            .resizable()
                            .scaledToFit()
                            .frame(height: 40)
                    }
                    .padding(.trailing)
                }
                shareCard
                Button(action: {
                    shareCardAsImage = shareCard.snapshot()
                    showShareSheet.toggle()
                }) {
                    HStack {
                        Image(systemName: "square.and.arrow.up")
                            .font(.system(size: 20))
                        Text("Share")
                            .font(.headline)
                    }
                    .frame(minWidth: 0, maxWidth: .infinity, minHeight: 50, maxHeight: 50)
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(20)
                }
                .padding(.horizontal)
                //Spacer()
            } //End of Master VStack
            .sheet(isPresented: $isShowingLibrary) {
                ImagePicker(sourceType: .photoLibrary, workoutImage: $workoutImage)
            }
            .sheet(isPresented: self.$showShareSheet) {
               if let unwrappedImage = shareCardAsImage {
                    ShareSheet(photo: unwrappedImage)
               }
            }
            .navigationBarHidden(true)
            .navigationTitle("")
        }
    }
}



extension View {
    func snapshot() -> UIImage {
        let controller = UIHostingController(rootView: self)
        let view = controller.view
        
        //This looks better:  let targetSize = CGSize(width: 400, height: 300)
        let targetSize = controller.view.intrinsicContentSize
        view?.bounds = CGRect(origin: .zero, size: targetSize)
        view?.backgroundColor = .clear

        let renderer = UIGraphicsImageRenderer(size: targetSize)

        return renderer.image { _ in
            view?.drawHierarchy(in: controller.view.bounds, afterScreenUpdates: true)
        }
    }
}





import LinkPresentation


//This code is from https://gist.github.com/tsuzukihashi/d08fce005a8d892741f4cf965533bd56

struct ShareSheet: UIViewControllerRepresentable {
    let photo: UIImage
          
    func makeUIViewController(context: Context) -> UIActivityViewController {
        let text = ""
        let itemSource = ShareActivityItemSource(shareText: text, shareImage: photo)
        
        let activityItems: [Any] = [photo, text, itemSource]
        
        let controller = UIActivityViewController(
            activityItems: activityItems,
            applicationActivities: nil)
        
        return controller
    }
      
    func updateUIViewController(_ vc: UIActivityViewController, context: Context) {
    }
}

class ShareActivityItemSource: NSObject, UIActivityItemSource {
    
    var shareText: String
    var shareImage: UIImage
    var linkMetaData = LPLinkMetadata()
    
    init(shareText: String, shareImage: UIImage) {
        self.shareText = shareText
        self.shareImage = shareImage
        linkMetaData.title = shareText
        super.init()
    }
    
    func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
        return UIImage(named: "AppIcon ") as Any
    }
    
    func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
        return nil
    }
    
    func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
        return linkMetaData
    }
}

[ad_2]

Source link

Leave a Reply

Your email address will not be published.