Skip to content

Developer Tools2 min read

Colors in Xcode: dark mode, high contrast and generated symbols

Name colors by role, keep dark and high-contrast variants in one color set, use the symbols Xcode generates and check contrast with numbers — plus the grey that failed our own accessibility tests.

Colors look like the easiest part of an app until you add dark mode, a second platform and a designer who renames "blue" for the third time. A little structure in the asset catalog saves a lot of hex codes scattered through the code.

Name colors by role, not by value

A color called blue500 tells you what it looks like; a color called textSecondary or statusSuccess tells you what it is for. Role-based names survive redesigns: when the brand blue changes, you edit one color set and every screen follows. Start with a small set — background, elevated surface, primary and secondary text, accent, success, warning, error — and add more only when a real need appears.

One color set, several appearances

A Color Set in the asset catalog can hold different values for different conditions:

  • Any and Dark appearances, so the system switches automatically with dark mode;
  • High Contrast variants for people who turn on Increase Contrast in Accessibility settings;
  • a color space per value — sRGB for most colors, Display P3 when you need more saturated tones on modern screens.

Before reaching for custom colors, check the system ones: label, secondaryLabel, systemBackground and friends already adapt to dark mode and contrast settings.

Use the generated symbols

Since Xcode 15, every color and image in an asset catalog gets a generated Swift symbol. No more string names that break silently after a rename:

swift
// SwiftUI: Xcode generates .statusSuccess and .surfaceElevated from the asset catalog
Text("Connected")
    .foregroundStyle(Color(.statusSuccess))
    .padding()
    .background(Color(.surfaceElevated))

// UIKit uses the same generated resources
let tint = UIColor(resource: .brandAccent)

If a color is renamed or deleted, the build fails instead of the app quietly showing nothing.

Check contrast with numbers

Readable text needs a contrast ratio of at least 4.5:1 against its background, or 3:1 for large text (WCAG AA). Eyeballing is not enough. While building our own console we picked a warm grey, #6F6B63, for secondary text on a #111111 card. It looked fine on our screens, but the measured contrast was only 3.56:1, and our automated accessibility tests rejected it. Switching to #A39F95 raised it to about 5.6:1 without changing the look of the design.

CheckTarget
Body text vs background4.5:1 or more
Large text (about 18 pt and up)3:1 or more
Dark modeMeasure again — dark variants fail differently
High ContrastProvide variants for key text and controls

Keep palettes consistent across apps

When one studio ships many apps, consistency becomes its own problem: every project starts with someone picking colors by hand. We built ColorsGen for exactly that moment. It builds a harmonious palette from a base color you choose — or generates one at random — and prepares it for Xcode in a few taps, on iPhone, iPad and Mac. For icons and image assets, see our guide to app icon sizes in 2026.

Tip

Add a contrast check to your UI tests or design review. It is the cheapest accessibility fix there is — and it catches problems before users do.

ShareXLinkedIn

ONLYAPPS team

Novi Sad, Serbia · onlyapps.org

Contact

We use analytics cookies only with your consent. Essential cookies keep the site working. Privacy policy