Global accent color not respected

I am facing an odd problem with the global accent color in a macOS application targeting macOS 11 +. The color is defined in an asset catalog and its name is set as the value of the key Global Accent Color Name in the project's build settings. Despite this, the custom accent color is not applied uniformly throughout the application when the system accent color is set to multicolor.

Anywhere where NSColor.controlAccentColor is used explicitly either in code or interface builder, the color is correct. However, wherever the use of the accent color (or its variants) is implicit, the blue system accent color is used instead. This includes the selection in NSMenus, the selected state of NSSegmentedControls, the selection NSOutlineView using the source list style, NSSwitch, NSPopUpButton, NSButton, etc.

This problem occurs in both light and dark modes, on macOS 11 and macOS 12. I have compiled the application with Xcode 12.5, and multiple versions Xcode 13.

I have found that modifying the system accent color to something other than multicolor and then back to multicolor fixes the problem, but only until the application is quit. At the next launch, the problem reappears. 

I have tried all sorts of changes such as:

  • Setting the value directly in info.plist
  • Adding the value in an xconfig file: with the key ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME
  • Forcing views to redraw
  • Renaming the color in the asset catalog
  • Creating a minimal application in an attempt to reproduce the problem.

The closest I have come to a solution is investigating in detail the effective appearance of the application, from the property NSApplication.sharedApplication.effectiveAppearance. 

The object returned is of the class NSCompositeAppearance. It contains an array of 2 appearances: an NSAquaAppearance or NSDarkAquaAppearance and an NSSystemAppearance.

 

Two private properties of NSAquaAppearance/NSDarkAquaAppearance are of interest: _tintColor and _cachedNormalizedBezelTintColor. These properties seem to set the color of standard controls. In my problematic application, _tintColor returns the system blue accent color. In other applications without these problems, _tintColor points to the color defined in the asset catalog. _cachedNormalizedBezelTintColor seems derived from _tintColor. 

Using key-value coding, I am able to modify these properties and change the appearance of most but not all controls, buttons, and selections. However, I do not want to use private properties and this is just masking the symptom of the real problem.

Has anyone experienced this problem with the global accent color? What was the solution?

Post not yet marked as solved Up vote post of Emilia_S Down vote post of Emilia_S
1.3k views
  • I'm seeing this as well on the macOS 13 beta. It's making it so I can't style the selection color of a NavigationList sidebar.

Add a Comment

Replies

I'm seeing the same problem with primary menu bar. Did you ever find a solution?

  • No, I still have this problem with more recent versions of Xcode and macOS.

Add a Comment

I have the exact same problem. Did you find a solution @Emilia_S ? @Emilia_S

Interestingly, the issue seems to arise when NSColor.controlAccentColor is called anywhere in the code.

Removing this reference resolves the issue. If you still need the accent color as a NSColor, you can use the following workaround

// ❌ breaks SwiftUI accent color
let color = NSColor.controlAccentColor

// ✅ uses the SwiftUI accentColor as value
let color = NSColor(.accentColor) 

I filed a radar under FB13688723