Supporting Dark Mode and more with Color Groups

Many controls have properties that allow you to change the color of one or more parts of the control. Color is also used when drawing entirely new, custom controls using the MobileCanvas control. While Xojo does support color constants for this purpose, they are insufficient for managing color when the user's device changes from light mode to dark mode or dark mode to light mode. They also provide no way for you to access colors predefined by the OS. Color Group objects solve these problems.

What is a Color Group?

A Color Group is a class you can add to your project (or instantiate via code) that can be either a single color or two colors (one for light mode and the other for dark mode). A Color Group object can be used in all the same ways you use the intrinsic Color type. The primary advantage of a Color Group is that when you use one, your app will automatically use the appropriate color when the user's device switches from light mode to dark mode and back.

A Color Group has three modes:




A single color which does not change when the OS changes from light mode to dark mode.


Two colors, one for light mode and the other for dark mode.


An OS-defined named color. For example, on iOS labelColor is a named color for labels which is black in light mode and white in dark mode.

Adding a Color Group to a project

You add a Color Group by choosing Color Group from the Insert toolbar button, from the Insert menu or dragging one from the Library to the Navigator.


Color Groups are supported for desktop, mobile and web projects.

Retrieving colors via code

You can retrieve named colors via code using the ColorGroup.NamedColor function:

NamedColor(name as String) As Color

This allows you to look up a named color based on the current state of the device/platform without having to create a ColorGroup first.


Named colors are case-sensitive.

As an example, you can get the previously mentioned labelColor like this:

Var myLabelColor As Color = ColorGroup.NamedColor("labelColor")

If you attempt to look up a named color which doesn't exist on the current OS, the iOS 13+ equivalent is returned.

If you attempt to look up a named color that doesn't exist at all, an InvalidArgumentException is raised.

If you attempt to look up a named color on a platform that doesn't support named colors (or Color Groups at all), an UnsupportedOperationException is raised.

All iOS controls which have Color properties now take Color Groups so they can change from light to dark automatically. Color Groups convert automatically to/from Colors.