Pattern · Settings
NewStorage SwiftUI Block
The Storage page of Settings: what the app takes in a split bar, Clear cache that confirms and counts down, removable downloads and options.
Where people see and reclaim the room an app takes. A summary card shows the total, the device's free space and a bar split into downloads, cache, photos and other; Clear cache confirms, works and shrinks its segment as the figures count down. Downloads remove from Edit or a long press, and the options cover cellular, quality and when finished downloads go.
- SwiftUI
- iOS 17.0+
- storage-settings
$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 total in the brand's face, with the device's free space beside it
- A bar and legend for downloads, cache, photos and other
- Clear cache confirms, then shrinks its segment as the figures count down
- Downloads that remove from Edit, a long press or VoiceOver
- Cellular, quality and auto-remove options bound to your settings
02
Implementation notes
How it behaves, what it handles, and the decisions behind it.
A summary card leads with "Used by this app" and the total in the brand's display face, the free space left on the device beside it, and a bar split into Downloads, Cache, Photos and Other, with a legend of each part's size under it. Clear cache asks first in a confirmation that names the size; once confirmed the button shows a spinner while your closure runs, then a checkmark and "Cleared 1.2 GB."; hand the block the new usage and the cache segment shrinks out of the bar while the total and legend count down, leaving the empty track behind. With no cache left the button reads "Cache is empty" and dims. A thrown error shows under the button. The Downloads card lists each download with its symbol, title, detail and size. Edit puts a remove control in front of every row, and a long press offers Remove download; either runs your closure with a spinner in the row, and the row leaves when your usage drops it. With nothing downloaded the card says "No downloads". Options hold Download over cellular as a switch, then Download quality and Remove finished as menus showing the current choice, all bound to your settings. Pass nil for the usage while you measure and the block shows grey shapes in its own layout.
Notes
StorageSettings(usage:options:showsFreeSpace:onClearCache:onRemove:). It is a section: no navigation stack, background, padding or scroll view of its own, so place it in your own column, such as aScrollViewwith.padding(.horizontal, 20).usageis aStorageSettings.Usagein bytes: thedownloadslist,cache(what downloads again when needed),photos(kept for offline use) andother(database, settings, logs).downloadBytesandtotalare computed.Usage.sampleis three downloads, 1.2 GB of cache and 4.8 GB in all. Measure it off the main actor, for example withFileManagerandURLResourceValues.totalFileAllocatedSize, and pass the new value after each change.- A
Downloadhas anid,title, optionaldetail("Audio · 52 min"), an SF Symbol for its kind and itsbytes. optionsis aBinding<StorageSettings.Options>:cellular(off by default),quality(.dataSaver,.standard,.high) andautoRemove(.never,.day,.week,.month). The block only writes the binding; apply the options where your downloads run.onClearCacheisasync throwsand runs after the person confirms. EmptyURLCache, your image cache and temporary files there, then set the new usage. Done holds for a few seconds before the button settles. Throw to show aLocalizedError'serrorDescription, or "The cache wasn't cleared. Try again." ACancellationErrorgoes back to rest quietly.onRemovereceives theDownload; delete its files and drop it from your usage. Several can run at once. A thrown error shows under the card. Nil hides Edit and the remove actions. Edit turns to Done and closes itself when the last download goes.showsFreeSpacereadsvolumeAvailableCapacityForImportantUsagefor the home directory, which needs no permission. Pass false to hide it.- The bar's full width is the largest total the block has seen, so a cleared cache leaves room on the track instead of stretching the other parts.
- Haptics: success when the cache clears and an error when it fails; a selection tick on the cellular switch.
- VoiceOver reads the summary as one element ("Used by this app, 4.8 GB. 41.2 GB free on this device"), each legend entry with its size, each download with its size and a Remove download action, and announces what was cleared or removed and any failure. Every target is at least 44 points tall. At accessibility sizes the legend becomes one column and rows wrap their text.
- Reduce Motion places the bar at its new value without the shrink, and other changes become short fades.
StorageSettingsExampleat the end ofStorageSettings.swiftis the Storage page from the preview: the sample usage, a cache clear that takes a moment and sets the cache to zero, and removals that drop the download. PasswrapsInNavigationStack: falseto push it in your own stack. The States preview shows the loading layout and an empty cache with no downloads.
Theming
- Reads
SPThemefrom@Environment(\.spTheme)and requires thedesign-systemitem. - Cards are
color.surfacewithradius.lgand 16 point padding (space.lg); rows useSPHairlinedividers inseparator, inset to the text. Groups sit 24 points apart (space.xl) undertype.headlinetitles. - The total is the one display moment: the brand's face (
type.face) at 34 points,type.numeralWeightcapped at semibold, intype.figureDesignwhen the face isn't bundled, with monospaced digits. The free space istype.footnoteintextSecondary. - The bar is a 12 point capsule on a
filltrack. Downloads aretextPrimary, Cacheaccent, PhotostextPrimaryat 45% and OthertextTertiary, so the accent marks what Clear cache frees. The legend istype.subhead, sizes intextSecondarywith monospaced digits. - Clear cache is a secondary button:
fillwithtextPrimaryintype.headline,radius.md, 52 points. Its note istype.footnoteintextSecondary, ordangeron a failure. The confirmation is the system's, with Clear cache as the destructive choice. - Rows: titles
type.bodyintextPrimary, detailstype.footnoteintextSecondary, symbolstextSecondary, sizes and menu valuestextSecondary, the menu chevronstextTertiary. The remove control isdangerwith astatusOnbar. Edit and Done aretype.subheadsemibold intextPrimary. - The cellular switch is
accentwith anaccentOnthumb when on andfillwith a white thumb when off. - The bar and figures move with
motion.smooth, states withmotion.snappy; both become short fades under Reduce Motion.
03
Keep building
Pieces that work well next to this one.