# Native iOS Settings Page Boilerplate in SwiftUI

> By Lawrence Arya, Founder & CEO of VP0. Published 2026-06-07. 6 min read.
> Source: https://vp0.com/blogs/native-ios-settings-page-boilerplate-swiftui

It looks like a pile of toggles. It is actually where compliance lives and where review passes or fails.

**TL;DR.** A settings page is underrated and review-critical: it is where compliance lives (in-app account deletion, legal links) and where AI builders generate worst, producing flat toggle piles with no grouping or persistence. Build it as a grouped native List or Form so it reads like Settings.app, with reusable row components (toggle, navigation, action, info) where toggles persist to real state via @AppStorage (a setting that does not survive a restart is a bug), destructive actions confirm, and the required App Store rows, in-app account deletion and legal links plus version, are built in. Complete it with Dynamic Type, VoiceOver, real dark mode, and honest deep-links to system Settings for OS permissions. A free VP0 design supplies the screens.

## Why does every app need a settings page, and why is it underrated?

Because it is the screen App Review checks, the screen users go to when something is wrong, and the screen AI builders generate worst. A settings page looks trivial, a list of toggles, so agents produce a flat pile of switches with no grouping, no persistence, and none of the required-by-Apple rows. But settings is where compliance lives (account deletion, privacy, the legal links), where the app's real state surfaces (notifications, appearance), and where a careless build quietly fails review. A good settings boilerplate is not decoration; it is the screen that keeps the app shippable.

The honest framing: settings is a **grouped, native [List](https://developer.apple.com/documentation/swiftui/list)**, not a custom layout, and the craft is using the platform's own grammar so the page feels like Settings.app rather than a web form. SwiftUI's `List` with sections, [`Form`](https://developer.apple.com/documentation/swiftui/form), and the standard row types give you the look for free, and fighting them with custom rows is the most common way a settings page ends up looking off.

## What is the standard anatomy?

The [Settings guidance](https://developer.apple.com/design/human-interface-guidelines/settings) and convention settle the structure into grouped sections, top to bottom:

| Section | Typical rows | Why it belongs |
| --- | --- | --- |
| Account | Profile, email, subscription, sign out | Who the user is and their plan |
| Preferences | Notifications, appearance, language | The app's real, persisted state |
| Privacy & Data | Permissions, data export, delete account | The compliance-critical section |
| Support | Help, contact, rate the app | The "something's wrong" exits |
| About | Version, legal, terms, privacy policy | The required-by-review rows |

Two rows are not optional. **Account deletion** is an App Store requirement for apps with account creation (it must be reachable in-app, not just on a website), and a settings boilerplate that omits it ships a rejection. And the **legal links** (terms, privacy policy) plus the version number are the rows reviewers look for. A boilerplate worth the name has these built in, because they are exactly what an AI-generated settings screen leaves out.

## What does "boilerplate" actually mean here?

Wiring, not just layout, because the rows have to do real things. Each row type is a small, reusable component with its behavior attached:

- **Toggle rows** bound to persisted state: a setting that does not survive an app restart is a bug, so toggles write to `@AppStorage`/UserDefaults (or your settings store) and reflect the real value on load, not a default.
- **Navigation rows** pushing to detail screens (notification preferences, appearance options) with the standard chevron and the platform's push.
- **Action rows** (sign out, delete account) that confirm destructive actions, sign out is a confirm, delete account is a serious, clearly-worded confirmation, never a one-tap accident.
- **Info rows** (version, build) that read real values rather than hardcoded strings.

The persistence is the part agents skip and the part that matters: a settings page is a contract that the user's choices stick, so the boilerplate's job is making each control read and write real state correctly. This is the same honest-state discipline as anywhere, applied to the screen where the user expects their preferences to be remembered.

## What completes a settings boilerplate?

The platform manners. Dynamic Type so rows grow with the system font, which scales text up to roughly 310% of the default at the largest accessibility size (settings is heavily used by accessibility users), VoiceOver labels on every control, a real dark-mode appearance (it is a settings page, it must look right in both), and the deep-link to the system Settings app where a permission lives outside your control (you cannot toggle the camera permission yourself, you send the user to iOS Settings, honestly). Account deletion deserves the honest flow specifically: a clear explanation of what deletion does, a confirmation, and a real backend call, not a fake success, the same no-dark-pattern discipline as [the account-deletion requirement](/blogs/user-account-deletion-flow-ios-requirement/).

The screens, the grouped settings list, the detail sub-pages, the delete-account flow, come as a free [VP0](https://vp0.com) design, so an agent generates the page with the required rows and the persistence wiring already in place, instead of a flat pile of toggles that fails review. A polished settings page is also where a [native iOS feel](/blogs/swiftui-memory-leak-ai-generated-code-fix/) shows: get it right and the whole app reads as native.

## Key takeaways: a SwiftUI settings boilerplate

- **Settings is underrated and review-critical**: it is where compliance lives and where AI builders generate worst.
- **Use a grouped native List/Form**, not a custom layout, so it reads like Settings.app rather than a web form.
- **The required rows are non-negotiable**: in-app account deletion and legal links plus version, exactly what agents omit.
- **Boilerplate means wiring, not just layout**: toggles persist to real state, destructive actions confirm, info rows read real values.
- **Platform manners complete it**: Dynamic Type, VoiceOver, real dark mode, and honest deep-links to system Settings for OS-level permissions.

## Frequently asked questions

**How do I build a native iOS settings page in SwiftUI?** Use a grouped List or Form with standard sections (Account, Preferences, Privacy and Data, Support, About), build reusable row components (toggle, navigation, action, info), and wire toggles to persisted state via @AppStorage so choices survive restarts. Include in-app account deletion and legal links. A free VP0 design supplies the grouped list and detail screens.

**Why do AI builders generate bad settings pages?** Because settings looks trivial, so agents produce a flat pile of toggles with no grouping, no persistence, and none of the required rows. The hard parts, persisting state correctly, including account deletion and legal links, and using native grouped-list grammar, are exactly what they skip, which is why a real boilerplate matters.

**What settings rows are required for the App Store?** In-app account deletion for apps with account creation (reachable in the app, not only on a website), plus links to terms and the privacy policy and a visible version number. Omitting account deletion is a common rejection, so a settings boilerplate must build these in rather than treating them as extras.

**How do I make settings toggles persist?** Bind each toggle to persisted state, @AppStorage or UserDefaults for simple values, or your settings store, so the control reflects the real saved value on load and writes on change. A toggle that resets after an app restart is a bug, and persistence is the part of a settings page that actually matters.

**Should the app handle permissions in its settings page?** Partly: you can show the current permission status, but you cannot toggle an OS-level permission like camera access from your app, so the honest pattern is a row that deep-links the user to the system Settings app to change it. Pretending to control a permission you cannot is misleading.

## Frequently asked questions

### How do I build a native iOS settings page in SwiftUI?

Use a grouped List or Form with standard sections (Account, Preferences, Privacy and Data, Support, About), build reusable row components (toggle, navigation, action, info), and wire toggles to persisted state via @AppStorage so choices survive restarts. Include in-app account deletion and legal links. A free VP0 design supplies the grouped list and detail screens.

### Why do AI builders generate bad settings pages?

Because settings looks trivial, so agents produce a flat pile of toggles with no grouping, no persistence, and none of the required rows. The hard parts, persisting state correctly, including account deletion and legal links, and using native grouped-list grammar, are exactly what they skip, which is why a real boilerplate matters.

### What settings rows are required for the App Store?

In-app account deletion for apps with account creation (reachable in the app, not only on a website), plus links to terms and the privacy policy and a visible version number. Omitting account deletion is a common rejection, so a settings boilerplate must build these in rather than treating them as extras.

### How do I make settings toggles persist?

Bind each toggle to persisted state, @AppStorage or UserDefaults for simple values, or your settings store, so the control reflects the real saved value on load and writes on change. A toggle that resets after an app restart is a bug, and persistence is the part of a settings page that actually matters.

### Should a settings page handle permissions?

Partly: you can show the current permission status, but you cannot toggle an OS-level permission like camera access from your app, so the honest pattern is a row that deep-links the user to the system Settings app to change it. Pretending to control a permission you cannot is misleading.

---
*Published on the [VP0 Journal](https://vp0.com/blogs). Free to read, index and cite with attribution.*
