ThemeGradient

open class ThemeGradient : NSGradient

ThemeGradient is a NSGradient subclass that dynamically changes its colors whenever a new theme is make current.

Theme-aware means you don’t need to check any conditions when choosing which gradient to draw. E.g.:

ThemeGradient.rainbowGradient.draw(in: bounds, angle: 0)

The drawing code will draw with different gradient depending on the selected theme. Unless some drawing cache is being done, there’s no need to refresh the UI after changing the current theme.

Defining theme-aware gradients

The recommended way of adding your own dynamic gradients is as follows:

  1. Add a ThemeGradient class extension (or TKThemeGradient category on Objective-C) to add class methods for your gradients. E.g.:

    In Swift:

    extension ThemeGradient {
    
        static var brandGradient: ThemeGradient {
           return ThemeGradient.gradient(with: #function)
        }
    
    }
    

    In Objective-C:

    @interface TKThemeGradient (Demo)
    
    + (TKThemeGradient*)brandGradient;
    
    @end
    
    @implementation TKThemeGradient (Demo)
    
    + (TKThemeGradient*)brandGradient {
       return [TKThemeGradient gradientWithSelector:_cmd];
    }
    
    @end
    
  2. Add Class Extensions on any Theme you want to support (e.g., LightTheme and DarkTheme - TKLightTheme and TKDarkTheme on Objective-C) to provide instance methods for each theme gradient class method defined on (1). E.g.:

    In Swift:

    extension LightTheme {
    
        var brandGradient: NSGradient {
           return NSGradient(starting: NSColor.white, ending: NSColor.black)
        }
    
        }
    
        extension DarkTheme {
    
        var brandGradient: NSGradient {
           return NSGradient(starting: NSColor.black, ending: NSColor.white)
        }
    
    }
    

    In Objective-C:

    @interface TKLightTheme (Demo) @end
    
    @implementation TKLightTheme (Demo)
    
    - (NSGradient*)brandGradient
    {
       return [[NSGradient alloc] initWithStartingColor:[NSColor whiteColor] endingColor:[NSColor blackColor]];
    }
    
    @end
    
    @interface TKDarkTheme (Demo) @end
    
    @implementation TKDarkTheme (Demo)
    
    - (NSGradient*)brandGradient
    {
       return [[NSGradient alloc] initWithStartingColor:[NSColor blackColor] endingColor:[NSColor whiteColor]];
    }
    
    @end
    
  3. If supporting UserTheme‘s, define properties on user theme files (.theme) for each theme gradient class method defined on (1). E.g.:

    displayName = Sample User Theme
    identifier = com.luckymarmot.ThemeKit.SampleUserTheme
    darkTheme = false
    
    orangeSky = rgb(160, 90, 45, .5)
    brandGradient = linear-gradient($orangeSky, rgb(200, 140, 60))
    

Fallback colors

Unimplemented properties/methods on target theme class will default to fallbackGradient. This too, can be customized per theme.

Please check ThemeColor for theme-aware colors and ThemeImage for theme-aware images.

  • ThemeGradient gradient selector used as theme instance method for same selector or, if inexistent, as argument in the theme instance method themeAsset(_:).

    Declaration

    Swift

    @objc public var themeGradientSelector: Selector?
  • Resolved gradient from current theme (dynamically changes with the current theme).

    Declaration

    Swift

    @objc public var resolvedThemeGradient: NSGradient?
  • Create a new ThemeGradient instance for the specified selector.

    Declaration

    Swift

    public class func gradient(with selector: Selector) -> ThemeGradient?

    Parameters

    selector

    Selector for color method.

    Return Value

    A ThemeGradient instance for the specified selector.

  • Gradient for a specific theme.

    Declaration

    Swift

    public class func gradient(for theme: Theme, selector: Selector) -> NSGradient?

    Parameters

    theme

    A Theme instance.

    selector

    A gradient selector.

    Return Value

    Resolved gradient for specified selector on given theme.

  • Current theme gradient, but respecting view appearance and any window specific theme (if set).

    If a NSWindow.windowTheme was set, it will be used instead. Some views may be using a different appearance than the theme appearance. In thoses cases, gradient won’t be resolved using current theme, but from either lightTheme or darkTheme, depending of whether view appearance is light or dark, respectively.

    Declaration

    Swift

    public class func gradient(for view: NSView, selector: Selector) -> NSGradient?

    Parameters

    view

    A NSView instance.

    selector

    A gradient selector.

    Return Value

    Resolved gradient for specified selector on given view.

  • Forces dynamic gradient resolution into resolvedThemeGradient and cache it. You should not need to manually call this function.

    Declaration

    Swift

    @objc open func recacheGradient()
  • Clear all caches. You should not need to manually call this function.

    Declaration

    Swift

    @objc static open func emptyCache()