All Versions
Latest Version
Avg Release Cycle
158 days
Latest Release
2175 days ago

Changelog History

  • v0.75 Changes

    October 11, 2017

    πŸ’… Stylish styles would sometimes fail to render or would render as errors (red stripe pattern) on the storyboard, particularly when first opening a project in Xcode. This is now fixed!

    πŸ‘ Lowered target / minimum iOS version from 10.0 to 9.0 because Stylish has no dependencies on iOS 10 or above, and so why not support more projects with backward compatibility?

  • v0.9.4 Changes

    June 23, 2019

    πŸ’… You can now define and reuse constant values inside a JSON stylesheet, thanks to @lucaslt89


       "constants" : {
          "PrimaryBackground": "#3849DE"
        } ,
        "styles" : [
              "styleName": "DefaultButton",
              "styleProperties": {
                 "titleColorForNormalState": "#D35400",
                 "backgroundColor": "$PrimaryBackground",
                 "borderColor": "#FDE3A7",
                 "cornerRadius": 6.0

    The Swift version is now bumped to 5.0, also thanks to @lucaslt89

  • v0.9.3 Changes

    November 04, 2018

    Compatibility Note:

    πŸš€ This release has breaking API changes for projects which have custom PropertyStylers. The Property Styler protocol has been updated to add a bundle parameter to the static apply function.

    Before: static func apply(value: PropertyType?, to target: TargetType)
    Now: static func apply(value: PropertyType?, to target: TargetType, using bundle: Bundle)

    πŸ’… Any existing custom PropertyStylers will need to update their apply function to include the additional parameter.

    πŸ†• NEW: Bundle Awareness

    ⚑️ More and more, the preferred pattern for defining UIImages and UIColors for use in an iOS project is via an asset catalog. Defining images and colors in an asset catalog allows Xcode and UIKit to optimize what is included in the final app binary, and in the case of colors specifically, asset catalogs allow variations of the same named color to be defined for P3 vs. sRGB gamuts, for dark mode vs. light mode, etc.

    When using colors and images defined in the asset catalog, the API follows the pattern:

    UIImage(named: String, in: Bundle?, compatibleWith: UITraitCollection?)
    UIColor(named: String, in: Bundle?, compatibleWith: UITraitCollection?)

    πŸ’… So in order for Stylish PropertyStylers to effectively leverage these APIs, they must have knowledge of which Bundle to load images, colors, or other resources from.

    πŸ’… For this reason, the Stylesheet protocol now has a new bundle property with a default implementation that loads the bundle that the Stylesheet itself is a member of. This bundle value is now passed down into all PropertyStylers at the moment they are invoked on a target view. This allows the PropertyStylers to pull any assets from the correct bundle at the moment they run.

    Future Evolution

    πŸ’… The big picture is that this enables Stylesheets to be distributed in their own framework bundle with all the assets they need to work. So a great Stylesheet that depends on specific colors with dark mode variations and specific image assets can now be placed in its own framework with a asset catalog, and distributed independently of any specific application. And when that Stylesheet is linked, imported and set in a host application, it will just work, and the styles will use the assets and colors from the bundle the Stylesheet came from. This also enables multiple "stylesheet bundles" to be linked into a single application and dynamically switched between without the host app having to independently include and name the various assets needed by those stylesheets.

    This helps finally define a pattern that allows Stylish to be used easily in important ways:

    • πŸ’… Stylesheet bundles can be authored and distributed as standalone projects that can be used in any app that uses Stylish
    • Companies or teams that want to create standard themes and reuse them across multiple apps can now do so!

    πŸ’… Upcoming versions of Stylish will include an updated example project to demonstrate this improved method of distributing and linking in Stylesheet bundles.

  • v0.9.2 Changes

    October 03, 2018

    Compatibility Note:

    πŸš€ This release has breaking API changes for projects which have create their own custom Styleable components or which for some other reason call Stylish.applyStyleNames() directly. The first change is an addition to the Styleable protocol which now requires a get/set property stylesheet: String?. For Stylish's built-in styleable components as well as for custom components, this should be implemented as an IBInspectable property. The didSet for this property (as well as for the existing styles property) should simply call through to Stylish like this:

    @IBDesignable class CustomStyleableView: UIView, Styleable {
        @IBInspectable public var styles: String = "" {
            didSet {
                Stylish.applyStyleNames(styles, to: self, using: stylesheet)
        @IBInspectable public var stylesheet: String? = nil {
            didSet {
                Stylish.applyStyleNames(styles, to: self, using: stylesheet)

    πŸ’… The second change is the new using stylesheet: String? parameter for the applyStyleNames() method above. For any places where this method was being called that wasn't in a custom component didSet as above, the existing behavior will be maintained by simply passing nil for the parameter.

    πŸ†• NEW: Cascading Stylesheet Overrides

    πŸ’… Until now, the most recent versions of Stylish have used a single global stylesheet which gets set for IBDesignable preview in the prepareForInterfaceBuilder() override, or in the app at startup (or anytime the global style should change).

    πŸ’… The single global stylesheet was used to apply all the styles set on all UI elements in the app.

    With this update, styleable components get a new inspectable property called stylesheet in Interface Builder and in code. The default value is nil, which uses the global stylesheet as usual. But setting a non-nil value on a styleable component will cause that component and all its descendant views to use that override stylesheet instead of the global stylesheet.

    πŸ’… In practical terms, this is useful for when apps have a light color scheme and a dark color scheme, with specific styling for buttons, text, etc. within each. Now, it's possible to set a single section of the screen to use one color scheme (and cascade that scheme down through its subviews) while the rest of the screen or app uses the other. This is also useful for A/B testing, user customization, or other scenarios where the whole app should retain its usual style, but some sub-section of it needs to use a secondary or tertiary stylesheet.

    πŸ’… In terms of organization this is also a win. Instead of a single monolithic stylesheet with styles named along the lines of:



    πŸ’… You can now have two stylesheets:

    πŸ’… ####Primary Stylesheet

    πŸ’… ####Secondary Stylesheet

    πŸ’… And instead of assigning the primaryTextOnSecondaryBackground style to labels, you can simply assign all labels either "primaryText" or "secondaryText" and then override the stylesheet for the section they are in to be "Secondary" if you wish to flip a group of labels to the "primary text on secondary background" style.

    πŸ’… Registering Stylesheets

    πŸ’… In order to connect the override stylesheet names you provide in Interface Builder or set in code to actual Stylesheets, you must register them with Stylish. To see override stylesheets working and cascading in Interface Builder / IB Designable previews, you must add this registration to your prepareForInterfaceBuilder() override, where you also set the global stylesheet, for example:

    extension UIView {
        // This is the only entry point for setting global variables in Stylish for Interface Builder rendering (since App Delegate doesn't get run by IBDesignable. So we are setting up the global stylesheet that we want used for IBDesignable rendering here.
        open override func prepareForInterfaceBuilder() {
            Stylish.stylesheet = Graphite()
            Stylish.register(stylesheet: Graphite(), named: "Graphite")
            Stylish.register(stylesheet: Aqua(), named: "Aqua")
            Stylish.register(stylesheet: JSON(), named: "JSON")

    πŸ’… In the above example, you could now use the override stylesheet names "Graphite", "Aqua" and "JSON" in your storyboards to use a different stylesheet for some section of the screen.

    πŸ’… Don't forget to also register the same stylesheets in your App Delegate or somewhere similar so they are also available at runtime (not just for Interface Builder previews!)

    Approaching v1.0

    Based on feedback, Stylish is being used successfully in a lot of real-world projects now. It feels like it's about time to officially call it a version 1.0, suitable for use in most applications. If you have encountered any issues or have concerns as to why it might not be ready for prime time, please get in touch!

  • v0.9.1 Changes

    September 29, 2018

    ⚑️ Updated for compatibility with the latest Swift syntax and UIKit masking changes

  • v0.9 Changes

    November 08, 2017

    A long time coming, Stylish has been reimplemented to be:

    • Clearer
    • πŸ’… More concise / less code required to create styles and stylesheets
    • More easily integrated as a separate module into client apps with more consistent storyboard rendering
    • Easier to customize and extend

    πŸ’… In addition, the included default components have been expanded to include StyleableUITextField and StyleableUITextView, in addition to the existing StyleableUIView, StyleableUILabel, StyleableUIButton, and StyleableUIImageView. Existing components have been expanded to have more styleable properties.

    πŸš€ Stylish is now in Swift 4 and so this new release is only compatible with Swift 3.2 or Swift 4.0 projects, although it supports targets back to iOS 9.0.


    πŸ’… The Stylish APIs have been reworked significantly, as has the schema for JSON stylesheets. Please see the updated example project and readme in this repo for details.

  • v0.7 Changes

    October 01, 2017

    Due to some early obstacles with IBDesignable and resolving types and resources across bundles, Stylish has until now been a single large Swift file that gets dropped into a client app. This, however, makes it difficult to manage as a dependency, and can also create problems for apps that want to use Stylish while also using a library that itself uses Stylish.

    πŸš€ Happily, this is now fixed and Stylish is a Swift framework that can be included as a subproject (using Apple's current recommendations) and linked into a client app target. This release includes a lot of reorganization to enable that, and also includes a variety of other improvements that have been needed or requested:

    πŸ›  Fixes Issue #7 by changing JSONStyleProperty from an enum with a fixed number of cases to a type that client apps can register new instances of, to allow the parsing of different kinds of properties from JSON stylesheets

    πŸ›  Fixes Issue #9 by creating static methods on Stylish that allows client apps to register their own custom dynamic property sets and shared style classes without needing to subclass existing Stylesheets (like JSONStylesheet) to override them.

    ⚑️ Updated to the StylishExample project to demonstrate usage and linking of Stylish as a framework

    ⚑️ Updated to recommended project settings for Xcode 9

    βž• Added additional comments, cleanup, small fixes throughout

  • v0.6 Changes

    September 18, 2016
    • πŸ“œ Informative Error messaging added for JSON parsing instead of silent failure on invalid JSON
    • πŸ’… Check and load the latest modified version of stylesheet.json from Documents directory or bundle
    • πŸ’… Implemented copy-on-write for Style Class property storage so changes to value on one copy of a Style Class instance doesn't effect other copies
    • πŸ‘ Method renaming to better adhere to Swift 3 API design guidelines
    • πŸ’… Moved the refreshStyles(for:UIView) method to be a static func on Stylish, and automatically refresh styles for all views in all windows when the GlobalStyleSheet is changed
  • v0.5 Changes

    June 10, 2016

    πŸ”– Version 0.5 contains the first major cleanup and polish pass, along with some significant changes:

    • βœ‚ Removed MutableStyleClass protocol as unnecessary to protect against shared mutable state since style classes are reinitialized for each consumer
    • βž• Added StylePropertySet protocol and struct concept as a new mechanism for grouping properties for different types of views. This is for easier location of desired properties, clearer context, and to avoid collision of multiple properties with the same name that do different things in different classes. This change also allows for easier declarations of style properties that no longer require arcane calls to computed getters and setters
- Added DynamicStylePropertySet protocol to optionally and additionally implement a way to interact with style properties using string identifiers instead of direct reference. This is necessary to work with dynamic stylesheets composed at runtime from, for example, JSON files

    • πŸ’… Full JSONStylesheet support and implementation. Now all properties and values currently styleable via code are now able to be expressed in JSON as well.
    • πŸ’… Updated Stylish Example project to use all the new changes, and to demonstrate a fully equivalent stylesheet defined in JSON
    • ⚑️ Large update to README and code comments added throughout project