Block · Account

New

Account Settings SwiftUI Block

The account section at the top of Settings: profile and photo, appearance, notifications, your data, sign out and deletion.

The part of Settings every app with accounts needs. A profile card changes the photo and the name in place, appearance shows System, Light and Dark as small screens in your theme's colors, and notification toggles know when iOS has notifications off. Export my data, Sign out and Delete account each confirm and show their own working, done and failed states.

  • SwiftUI
  • iOS 17.0+
  • account-settings
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.

  • Profile with a photo picker and in-place name editing
  • System, Light and Dark drawn in your theme's own colors
  • Notification toggles that ask for permission and offer Open Settings when it's off
  • Export my data and policy links in a Privacy and data group
  • Sign out with a confirmation and a deletion sheet with an explicit second step

02

Implementation notes

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

A profile card shows the avatar (your photo, a photo at a URL, or initials on a quiet circle), the name with an optional plan label, the email and Edit, which opens your profile editor or turns into a name field with Save and Cancel; with onChangePhoto the avatar opens the photo picker, shows the new photo at once with a spinner over it while you upload, and puts the old one back with a line under the card if the upload throws. Appearance offers System, Light and Dark as three small screens drawn in the theme's own light and dark colors, with a ring on the choice. Notification toggles bind to your preferences; the first turn-on asks iOS for permission, and when notifications are off for the app the card says "Off in Settings" with Open Settings and dims the toggles until they come back. Export my data runs your request, shows a spinner, then "We'll email a link to maya@example.com." with a checkmark, or the error with a retry glyph. Privacy policy and Terms of service open in the browser. Sign out asks first, then shows progress or its failure in the row. Delete account opens a sheet that lists what goes, needs "I understand this can't be undone." before the button arms, and shows working, done and failed in the button. The version line closes the section. Pass nil for the account while it loads and the profile card shows grey shapes in its own layout.

Notes

  • AccountSettingsBlock(account:appearance:notifications:notificationPermission:privacyPolicy:terms:version:deletionNotes:onEditProfile:onRename:onChangePhoto:onExportData:onSignOut:onDeleteAccount:) takes one Account, two bindings and the closures. Only account, the bindings and onSignOut are required; every other row hides when you leave its value or closure out. It is a section: no navigation stack, background, padding or scroll view of its own, so place it in your Settings column, a ScrollView with .padding(.horizontal, 20), or a sheet.
  • AccountSettingsBlock.Account holds name, email, an Avatar (.initials, .image(Image) or .url(URL), which loads with AsyncImage and shows initials until it arrives) and an optional plan label. initials takes the first letters of the first and last words. Account.sample is Maya from the preview.
  • appearance binds an AccountSettingsBlock.Appearance (.system, .light, .dark). Apply it at your root with .preferredColorScheme(appearance.colorScheme); the block only changes the value.
  • notifications binds [NotificationPreference], each with an id, title, optional detail and SF Symbol, and isOn. Empty hides the group. NotificationPreference.samples are the three in the preview.
  • notificationPermission is an optional NotificationPermission (.allowed, .denied, .notDetermined). Leave it nil and the block reads UNUserNotificationCenter whenever the app becomes active, asks for authorization the first time a toggle turns on, and turns that toggle back off if the person declines. Pass your own value when your app manages the request.
  • onEditProfile opens your editor from Edit. Without it, onRename edits the name in place: a 52 point field with the name content type and a Done key, Save and Cancel under it, "Enter your name." for an empty name, and your thrown error's message under a red stroke.
  • onChangePhoto receives the picked photo as JPEG data, scaled to at most 1024 points on its long side. Upload it, then pass the new avatar. Nil makes the avatar static.
  • onExportData, onSignOut and onDeleteAccount are async throws. The block shows working, done and failed itself, and a failure shows your error's errorDescription or a plain default ("The export didn't start. Try again.", "Couldn't sign out. Try again.", "Your account wasn't deleted. Try again."). Throw CancellationError() to go back to rest quietly. A successful deletion shows a checkmark and closes the sheet; sign the person out from your closure.
  • deletionNotes lists what deleting removes, by default your profile and sign-in, everything created or saved, and that a subscription keeps renewing until it is cancelled in the App Store. version defaults to AccountSettingsBlock.appVersion ("Version 2.4 (318)" from the bundle); nil hides it.
  • Haptics: a selection tick for appearance and each toggle, success when an export or deletion finishes, an error when an action fails.
  • VoiceOver reads the profile as one element, groups have headers, toggles are native switches through accessibilityRepresentation, the appearance choice carries the selected trait, and results are announced. At accessibility sizes the profile stacks, Appearance becomes a list of rows with a checkmark, the symbol column scales with the text, and nothing truncates except the email's middle on one line at default sizes.
  • Reduce Motion turns state changes into short fades.
  • AccountSettingsBlockExample at the end of AccountSettingsBlock.swift is the Settings screen in the preview: Maya on Plus, three notification preferences, a privacy policy, and stub closures that take a moment and succeed, so renaming, a new photo, the export, signing out and deleting all show their states. It reads the theme from the environment, or pass a brand.

Theming

  • Reads SPTheme from @Environment(\.spTheme) and requires the design-system item.
  • Cards are color.surface with radius.lg and 16 point padding; rows are at least 52 points, with SPHairline dividers in separator inset to the text; groups sit 24 points apart (space.xl) under type.headline titles.
  • Rows use type.body in textPrimary, second lines type.footnote in textSecondary, symbols type.body in textSecondary in a 24 point column, trailing arrows textTertiary. The email is type.subhead, the plan label type.caption on fill, the version type.caption in textTertiary.
  • The initials are type.display(20) in textSecondary on fill; the camera badge is textPrimary with a surface glyph and ring.
  • The appearance screens are drawn with the theme's own bg, surface, fill, textPrimary, textTertiary and accent, resolved in light and dark; the selection ring is accent.
  • Toggles are accent with an accentOn thumb when on and fill with a white thumb when off. Plain buttons (Edit, Save, Open Settings) are type.subhead semibold in textPrimary; Cancel is textSecondary.
  • Delete account and its symbol are danger; in the sheet the button is danger with statusOn text in type.headline and radius.md, Cancel is fill with textPrimary. Field focus strokes textPrimary, errors danger, the export's done mark success.
  • State changes use motion.snappy, the placeholder appears with motion.smooth, and every animation becomes a short fade under Reduce Motion.