20

What is the default background UIColor of UITableViewCell? I need a constant UIColor object rather than RGB as I wish to implement dark mode in iOS 13. (I couldn't find any matching color such as [UIColor systemBackgroundColor]).

I placed a breakpoint at willDisplayCell:forRowAtIndexPath: and printed cell.backgroundColor. This is what I got:

<UIDynamicSystemColor: 0x600000bf2c00; name = tableCellGroupedBackgroundColor>

It seems like a private class with no public equivalent. Any suggestions how to target this?

Joshua
  • 1,974
  • 2
  • 23
  • 39

2 Answers2

50

Cells in a plain styled table view use UIColor.systemBackground[Color] for their background, UIColor.label[Color] for the title text, and UIColor.secondaryLabel[Color] for the subtitle text.

For a grouped style table view, the cell background uses UIColor.secondarySystemGroupedBackground[Color] and the table view background uses UIColor.systemGroupedBackground[Color].

All of these adapt to light/dark mode.

Below is a helpful UIColor extension that allows you to print the light and dark description of any color.

extension UIColor {
    var lightDarkDescription: String {
        let lightTraits = UITraitCollection.init(userInterfaceStyle: .light)
        let darkTraits = UITraitCollection.init(userInterfaceStyle: .dark)
        let lightColor = self.resolvedColor(with: lightTraits)
        let darkColor = self.resolvedColor(with: darkTraits)
        if lightColor == darkColor {
            return self.description
        } else {
            return "\(self), light: \(lightColor), dark: \(darkColor)"
        }
    }
}

Examples:

print(UIColor.secondarySystemGroupedBackground.lightDarkDescription)
print(UIColor.secondaryLabel.lightDarkDescription)
print(UIColor.green.lightDarkDescription)

Output:

<UIDynamicSystemColor: 0x6000005a5d80; name = secondarySystemGroupedBackgroundColor>, light: UIExtendedGrayColorSpace 1 1, dark: UIExtendedSRGBColorSpace 0.109804 0.109804 0.117647 1
<UIDynamicSystemColor: 0x6000005a5f00; name = secondaryLabelColor>, light: UIExtendedSRGBColorSpace 0.235294 0.235294 0.262745 0.6, dark: UIExtendedSRGBColorSpace 0.921569 0.921569 0.960784 0.6
UIExtendedSRGBColorSpace 0 1 0 1

If anyone wants to play with all of the colors, see my SystemColors demo app on GitHub.

Daniel
  • 8,794
  • 4
  • 48
  • 71
rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • Brilliant! Thank you so much for helping out! May I ask what is your reference? I searched endlessly for an answer and couldn't find anything useful... So out of curiosity, it will be interesting to realize the source of information. – Joshua Jul 24 '19 at 17:24
  • 2
    Largely trial and error. Last month I wrote a simple table view app that has a row for every UIColor constant using that color as the row's background. This lets me see all of the colors in both light and dark mode. I then compared the colors I see in the Contacts and Settings apps with what I see in my test app. The tricky part is that many of the predefined colors are partially transparent. – rmaddy Jul 24 '19 at 17:28
  • 2
    @Joshua I added a link to the app I created to play with all of the colors. – rmaddy Jul 25 '19 at 05:44
  • Did anyone dig even deeper and found out where the name `tableCellGroupedBackgroundColor` in the OPs question comes from? Or is this just another helper color that switches between grouped and plain table views? – Klaas Oct 17 '19 at 11:54
  • 1
    At least the `UIUserInterfaceLevel` of a trait collection seems to be taken into account when the `tableCellGroupedBackgroundColor` resolves its color. I get different cell background colors depended on having the table view in a root level view controller or a presented view controller. – Klaas Oct 17 '19 at 12:29
  • same @Klaas but seemingly only on iPad. I just made a color asset with light = white, dark = the above RGB color and used that instead of the default everywhere – Jesse Naugher Oct 28 '19 at 20:37
  • One caveat for the `UIColor.systemGroupedBackground`. If the `UITableView.Style` is `.insetGrouped` and the tableView is layed out in a viewController that was presented with `presentationStyle = .pageSheet`, the darkMode color is different. – David May 09 '20 at 22:57
  • These only exist in iOS 13. Any idea how to get the system background color on systems running older iOS versions? – fishinear Aug 05 '20 at 19:39
  • @Klaas `tableCellGroupedBackround` was removed starting from iOS 6. `systemGroupedBackground` was added in iOS 13. For several years the only way to get this colour was to hard code the RGB values. – Abhi Beckert Feb 22 '21 at 01:44
  • @AbhiBeckert If you inspect a grouped UITableView (iOS 14) in Xcode 12.5 , it reports that cell is still using "tableCellGroupedBackgroundColor". The documentation is misleading; it says that that "groupTableViewBackgroundColor is now the same as systemGroupedBackgroundColor" when in fact, a grouped tableViewCell's background color actually uses secondarySystemGroupedBackground. Cheers. – Womble Aug 19 '21 at 00:12
9

In iOS 13, to support dark mode, you can use secondarySystemGroupedBackground for the cell background.

The Swift code:

if #available(iOS 13.0, *) {
    cellBackgroundColor = .secondarySystemGroupedBackground
} else {
    cellBackgroundColor = .white
}

Correspondingly, for group table view background, you can use (primary) systemGroupedBackground.

The new semantic colors are for groups, containing other groups (primary -> secondary -> tertiary), and not limiting to table views. It makes perfect sense. I wrote about it here.

samwize
  • 25,675
  • 15
  • 141
  • 186