Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- SwiftUI View → UIImage Snapshot + Share Sheet
- ==============================================
- Renders any SwiftUI view into a UIImage, then presents the system share sheet
- with the image and accompanying text.
- Usage:
- func share() {
- let image = MyShareView()
- .frame(width: 380, height: 370)
- .snapshot
- let text = """
- Check out this coin on MyApp.
- Download for free: https://example.com
- """
- let activityItemSource = ActivityControllerItemSource(title: "MyApp", text: text)
- let activityViewController = UIActivityViewController(
- activityItems: [image, activityItemSource],
- applicationActivities: nil
- )
- // Required for iPad — present as popover
- if let popover = activityViewController.popoverPresentationController,
- let rootView = UIApplication.shared.window?.rootViewController?.view {
- popover.sourceView = rootView
- popover.sourceRect = .zero
- popover.permittedArrowDirections = []
- }
- UIApplication.shared.window?.rootViewController?.present(
- activityViewController,
- animated: true
- )
- }
- Snapshot extension:
- import SwiftUI
- import UIKit
- extension View {
- #if os(iOS)
- var snapshot: UIImage {
- let controller = UIHostingController(rootView: self)
- let view = controller.view
- let targetSize = controller.view.intrinsicContentSize
- view?.bounds = CGRect(origin: .zero, size: targetSize)
- view?.backgroundColor = Color.surface.uiColor
- let renderer = UIGraphicsImageRenderer(size: targetSize)
- return renderer.image { _ in
- view?.drawHierarchy(in: controller.view.bounds, afterScreenUpdates: true)
- }
- }
- #endif
- }
- ActivityControllerItemSource (custom share text + link preview metadata):
- import UIKit
- import LinkPresentation
- class ActivityControllerItemSource: NSObject, UIActivityItemSource {
- var title: String
- var text: String
- init(title: String, text: String) {
- self.title = title
- self.text = text
- super.init()
- }
- func activityViewControllerPlaceholderItem(_ activityViewController: UIActivityViewController) -> Any {
- return text
- }
- func activityViewController(_ activityViewController: UIActivityViewController, itemForActivityType activityType: UIActivity.ActivityType?) -> Any? {
- return text
- }
- func activityViewController(_ activityViewController: UIActivityViewController, subjectForActivityType activityType: UIActivity.ActivityType?) -> String {
- return title
- }
- func activityViewControllerLinkMetadata(_ activityViewController: UIActivityViewController) -> LPLinkMetadata? {
- let appIcon = UIImage(named: "AppIconRaw")
- let metadata = LPLinkMetadata()
- metadata.title = title
- metadata.iconProvider = NSItemProvider(object: appIcon ?? UIImage())
- metadata.originalURL = URL(fileURLWithPath: text)
- return metadata
- }
- }
- Notes:
- - Set an explicit .frame() on the view before calling .snapshot so intrinsicContentSize is correct.
- - Uses drawHierarchy(afterScreenUpdates: true) so async layout (images, etc.) has time to render.
- - `ActivityControllerItemSource` lets you attach a title, body text, and app icon to the share sheet preview.
- - On iPad, UIActivityViewController must be presented as a popover or it will crash.
Advertisement
Add Comment
Please, Sign In to add comment