Advanced Dark Mode

WWDC 2018

Posted by Den on September 28, 2018 · 20 mins read
Advanced Dark Mode

Advanced Dark Mode

WWDC 2018

Advanced Dark Mode

WWDC 2018

NSAppearance

  • Cocoa’s UI theme system
  • One view hierarchy for both light and dar
  • Underlies Dark Mode, High Contrast mode, and Touch Bar

NSAppearanceCustomization

  • Adopted by NSView and NSWindow
  • In 10.14, NSApplication conforms too

Appearance Source ( new )

  • Makes a window inherit appearance from another object
  • Assign nil to reset default inheritance

Custom Views

  • Do appearance-sensitive work in
  • Appearance changes will cause
  • Set needsUpdateConstraints needsLayout, or needsDisplay to trigger manually

Glow behind image

Customizing for High Contrast

  • High-contrast appearance names
  • Not available directly
  • Only via System Preferences
  • Pass to bestMatch(from:) to provide custom behavior

Managing Custom Sublayers

  • Custom sublayers don’t inherit appearance automatically
  • If possible, switch to using views
  • Otherwise, manage layers manually with
    - viewDidChangeEffectiveAppearance()
    - NSAppearance.current

Detecting Appearance Change ( new )

  • Good time to
    - Perform custom invalidation
    - Drop caches
  • No need to invalidate view itself !

Current Appearance

  • Thread-local state
    - Like NSGraphicsContext.current
  • Appearance used to resolve colors and images
  • Current appearance is set up automatically for
  • You can also set it yourself

NSImage as Layer Contents

  • Don’t
  • Do
    - If possible, switch to NSImageView
    - Automatically updates for appearance
    - Create a CGImage in updateLayer()

Materials

  • Dynamic backgrounds
  • Use effects like blur, tinting, and gradients
  • Provide depth, context, and beauty to the interface
  • Automatically used in
    - Window titlebars and backgrounds
    - Table views
    - Sidebar split view items
    - Popovers
    - Menus

NSVisualEffectView

  • A view that shows a material
  • Controls whether material uses active window look
  • By default, matches enclosing window
  • Controls whether material “punches through” window
  • Behind-window by default
  • Encapsulates effect definition

Semantic Materials ( new )

Materials

Nonsemantic materials are deprecated ⚠️

  • Light
  • Dark
  • Medium light
  • Ultra dard

Desktop-Tinted Materials

  • Automatic support
    -
    NSWindow, NSScrollView, NSTableView, NSCollectionView
  • Custom NSBox support
  • NSBox and NSVisualEffectView support
  • Untinted color in light
  • Desktop-tinted in dark
  • Tint effect might be disabled
Problem

Solution
  • Effect is provided by Quartz window server
  • Updates asynchronously from your app
  • But can’t draw with the color ( or get RGB values )
  • Instead, use maskImage

Mask Image

  • Masks the material to a shape
  • Drawing-handler images supported
  • Works with any material
  • Alpha channel used for mask
  • Only material (not subviews) masked
  • Provide a resizable image capInsets and resizingMode

Vibrancy

  • Lightens or darkens the content behind it
  • Similar to dodge and burn in a photo editor
  • Provided by “vibrant” NSAppearance objects
  • Override allowsVibrancy to return true
  • Blending effect automatically applies to your view and its descendants
  • Typically, draw with a label color depending on prominence
  • Avoid non grayscale colors

Vibrant Blending Tips

  • Vibrant blend mode applies to subtree
  • Typically only leaf views should be vibrant
  • Break non vibrant drawing out into a sibling view
  • Avoid overlapping vibrant and non-vibrant views
  • Don’t subclass Cocoa controls to override allowsVibrancy
  • Only override allowsVibrancy if you also override drawing

Background Styles ( new )

  • NSTableView now sets background style recursively
  • Label colors automatically adapt to emphasized style

Custom Selections

Selection Material

  • Selection material follow the accent color
  • Avoid drawing custom blue selections
  • Use NSVisualEffectView instead

Backward Deployment

  • System colors ( 10.10 + )
  • Asset catalog colors
  • Desktop-tinted materials
    - Desktop-tinted NSVisualEffectView materials are new in 10.14
    - Classes providing automatic materials
  • Manually enable or disable Dar Mode
    - Automatically opted in with 10.14 SDK
    - Info.plist key: NSRequiresAquaSystemAppearance
    Set to NO to enable Dark Mode with earlier SDKs
    Set to YES to disable it temporarily

Find Hardcoded Colors

  • Static named color
  • Hardcoded components

Offscreen Drawing

  • Prefer block-based NSImage over lockFocus
  • Other offscreen drawing techniques, including

Appearances in Interface Builder

  • Views set to Aqua won’t change dynamically
  • Choose “Inherited” to match the superview
  • NSVisualEffectView now automatically uses the correct vibrant appearance
  • Avoid overriding the appearance
    - Interface Builder: select “Inherited”
    - In code: set appearance to nil

Testing Appearances ( new )

  • Switch appearances from the Debug Bar and Touch Bar

Using the View Debugger ( new )

Enhancements in Xcode 10

  • System color names
  • Asset Catalog color names
  • NSAppearance configuration