# Interaction patterns in detail

Companion to `../SKILL.md` for the `hig-patterns` skill.

## Starting: launch and onboarding

- Launch straight into useful content. The launch screen should look like the
  first frame of the app, not a splash advert.
- Restore where the person left off (`@SceneStorage` for per-window state).
- Onboarding, permission timing and pre-permission screens:
  [onboarding-and-states.md](onboarding-and-states.md).
- Let people try the app before creating an account whenever possible.

## Waiting: loading and progress

- Show content as soon as any part is ready; load the rest progressively.
- Use `ProgressView(value:total:)` when progress is measurable and an
  indeterminate `ProgressView()` only for short, unknown waits.
- For content shaped placeholders use `.redacted(reason: .placeholder)` on a
  sample layout, which keeps the page from jumping when data arrives.
- Keep the interface usable during long work; allow cancellation.
- Pull to refresh with `.refreshable` on lists and scroll views.

## Nothing to show, or something went wrong

Empty, no-results and error states with `ContentUnavailableView`:
[onboarding-and-states.md](onboarding-and-states.md).

## Feedback and confirmation

- Confirm success quietly and in place: a checkmark symbol effect, an updated
  row, a brief haptic (see `ios-haptics`).
- Reserve alerts for failures that block progress.
- Make destructive actions recoverable (undo, trash) rather than piling on
  confirmation dialogs. Where there is no undo, confirm with a destructive-role
  button (`Button("Delete Order", role: .destructive)`).

## Undo

- Register reversible edits with `@Environment(\.undoManager)`; shake to undo on
  iPhone and Command-Z on iPad and Mac come with it.
- Swipe-to-delete in a list should either be undoable or confirmed.

## Search

- Add `.searchable(text:)` to the navigation container so the field sits where
  the platform expects it. Offer `.searchSuggestions` and `.searchScopes` for
  large catalogs.
- On iOS 26 a dedicated search tab (`Tab(role: .search)`) places search at the
  bottom within reach.
- Search as the person types when results are local; debounce remote queries.

## Entering data

- Ask only for what is needed; prefill what the app knows.
- Pick the right keyboard and content type (`.keyboardType(.emailAddress)`,
  `.textContentType(.emailAddress)`) so AutoFill works.
- Validate inline next to the field, after the person leaves it, not on every
  keystroke.
- Move focus with `@FocusState` and `.submitLabel(.next)`.

## Settings

- Put settings people change often inside the app; put rarely changed ones in a
  settings screen. On macOS use a `Settings` scene.
- Keep defaults good enough that most people never visit settings.

## Sharing, drag and drop, files

- Use `ShareLink` with a `Transferable` model; the same conformance powers
  `.draggable` and `.dropDestination`.
- For document-based apps, `DocumentGroup` provides the browser, open, save and
  rename behavior people expect.

## Accounts

- Offer Sign in with Apple wherever other third-party sign-in exists.
- Support passkeys and AutoFill for passwords.
- Provide in-app account deletion if the app lets people create an account.

## Notifications

- Notify about things people care about and that are time-sensitive, such as an
  order that has shipped. Group by thread and set an interruption level that
  matches urgency.
- Deep link into the exact content the notification describes.
