Pattern · Sheets and Alerts

New

Share Sheet SwiftUI Block

Your app's own share sheet: the item up top, recent people to send to, Copy link, Save, Collection, More and Report.

The content of a share and actions sheet for a post, article or file. A header shows the item, recent people and conversations sit in a strip you select from before sending with an optional message, and action tiles copy the link, save it, add it to a collection or open the system share sheet. Report confirms first, and every action shows its working, done and failed states.

  • SwiftUI
  • iOS 17.0+
  • share-sheet
Get SwiftPieces Pro

$199 once, every piece included. See how installing works · Sign in

01

What's included

SwiftUI source you own, built on Apple frameworks only.

  • The item in a header with its thumbnail, title, link and Close
  • Select recent people, add a message and Send, with Sent shown in place
  • Copy link answers Copied; Save and Collection run your closures
  • More opens the system share sheet with the item's preview
  • Report in the danger colour, confirmed first, plus a loading layout

02

Implementation notes

How it behaves, what it handles, and the decisions behind it.

A header card shows what is being shared: its thumbnail (or an SF Symbol on a quiet fill), its title over two lines and its link, with Close when the block sits in a presented sheet. Send to lists recent people and group conversations as avatars in a strip that scrolls sideways; a tap selects one with a ring and a check badge, and "2 selected" appears over the strip. Under the avatars, Add a message takes an optional note and Send names who it goes to ("Send to Priya and Jonah"), waits in a quiet fill until someone is picked, shows progress while your closure runs, then "Sent" under the button and under each avatar before the selection clears; a thrown error shows its message under the button. Four action tiles sit below: Copy link copies the URL and answers "Copied" with a check, Save toggles to "Saved" and back (rolling back if your closure throws), Collection runs your closure and reads "Added", and More opens the system share sheet with the item's preview. Report sits apart in the danger colour, confirms first, then reads "Reported. Thanks for letting us know." Pass nil while the item loads and the block shows grey shapes in its own layout.

Notes

  • ShareActionsSheet(item:people:thumbnail:onSend:onSave:onAddToCollection:onReport:onCopy:onClose:) takes one Item, the recent Person list and closures for the actions you support. Every closure is optional: leaving out onSend, onSave, onAddToCollection or onReport hides its part. Copy link and More always show.
  • It is the sheet's content, not the sheet. Present it in your own .sheet with .presentationDetents([.medium, .large]) inside a ScrollView with 20 point margins, or place it inline in any column. It brings no scroll view, background or padding of its own. The avatar strip is the one thing that scrolls, sideways.
  • ShareActionsSheet.Item holds the title, the url that Copy link and More share, a linkText (the URL's host by default), an SF symbol for when you pass no thumbnail, and isSaved. Item.sample is the article from the preview.
  • ShareActionsSheet.Person is an id, a name and isGroup, which draws a group symbol instead of initials. Send names one or two people by first name and counts beyond that. Person.samples holds the six from the preview. An empty list shows a quiet line instead of the strip.
  • onSend([Person], String) is async throws and receives the selected people in the order they were tapped and the trimmed message (empty when none). onSave(Bool) receives the new saved state. onAddToCollection and onReport are async throws; throw CancellationError() to back out quietly, or a LocalizedError to show its errorDescription.
  • thumbnail is an Image for the header and the system share preview. Copy link writes the URL to UIPasteboard and then calls onCopy for analytics. Close calls onClose, or dismisses the presenting sheet.
  • Haptics: a selection tick on each avatar, success when something is copied, sent, saved, added or reported, and an error when a closure throws.
  • VoiceOver reads each avatar by full name with its selected state and a hint, announces "Link copied", "Sent", "Saved" and "Reported", and reads Send's working and sent states as its value. At accessibility text sizes the tiles become rows with a symbol column so their labels keep the width.
  • Reduce Motion turns presses and state changes into short fades.
  • ShareActionsSheetExample at the end of ShareActionsSheet.swift is the article screen from the preview, with the sheet open at its medium detent; Send, Save, Collection and Report wait a moment, then succeed. Pass wrapsInNavigationStack: false to push it in your own stack.

Theming

  • Reads SPTheme from @Environment(\.spTheme) and requires the design-system item.
  • The header, the Send to card and the Report row are color.surface with radius.lg and 16 point padding; the tiles are surface at radius.md; groups sit 24 points apart (space.xl). The hairline under the avatars is separator.
  • Titles use type.headline, the link and tile labels type.footnote, names type.caption, the message field type.body.
  • Avatars, the thumbnail and the message field sit on fill; the field's stroke is separator, textPrimary while focused. Selection draws a textPrimary ring and a textPrimary badge with a surface check.
  • Symbols are textPrimary on the tiles and textSecondary elsewhere. Report is danger.
  • Send is the only accent: accent with accentOn in type.headline at radius.md once someone is picked, fill with textTertiary before.
  • State changes use motion.snappy, the item arriving motion.smooth; all become short fades under Reduce Motion.