Stylesheets For Storyboards

Related tags

SwiftUI App Stylish
Overview

Stylish

Stylesheets For Storyboards

Stylish is a library that lets you create stylesheets in code or in JSON for controlling virtually any property of your UIViews, UILabels, UIButtons, etc. as well as the properties of any custom views you create yourself.

The real magic happens in storyboards, however, where you can assign one or more styles to a view, label, button, etc. right inside the Interface Builder inspector, and immediately see the live preview of the applied styles right inside the storyboard. No need to compile or run the app in the simulator or on device, since Stylish uses @IBDesignable to apply styles at design time as well.

For the first time, this provides a single solution for creating and applying styles and themes that are rendered both in the running app and in the storyboard. So what you see at design time will finally match what users will see in the app.

  • Get the full benefits of a real styling system: update a style in one place, and every view using that style updates as well. Only now, they update both at runtime and in the storyboard.
  • Change the global stylesheet at any time, and the app instantly updates to reflect the new theme.
  • Stylish is completely customizable and extensible, but it comes with a full implementation of stylesheet parsing from JSON. Your app can even load updated stylesheets over the web and cache them as the new default theme, allowing you to tweak the the appearance or any other property of your objects after the app is deployed, or based on user, time of year, etc.
  • Stylish makes it easy to rapidly test our and iterate on designs right from Xcode: you can apply or remove multiple styles in real time, right from the storyboard and see immediately how they will look on device. Or, update your JSON stylesheet in one window while your storyboard auto-updates with the changes in another window.

Installation

Since Swift has not yet reached ABI or module format stability, Apple does not support or advise distributing Swift libraries compiled outside of your project. Instead, the recommended approach is:

  1. Include the Stylish repo (this repo) as a git submodule in your project (or just check out the version of the entire Stylish repo you want to use and add it to your project as a subdirectory)
  2. Drag Stylish.xcodeproj into your own Xcode project or workspace (see the StylishExample project in this repo as a reference)
  3. In your own app target(s) on the "General" tab, scroll down to "Embedded Binaries", click the plus button and choose Stylish.framework. Again, you can refer to the StylishExample project to see what this looks like.

These steps will ensure that the Stylish framework is compiled as part of your own app's build phases as needed and that the Stylish.framework will be using the same version of Swift and the Swift compiler as the rest of your project.

  1. IMPORTANT! Because Stylish is a separate module from your app, some special considerations are needed to get IBDesignables and the live rendering of styles in Storyboards playing nicely. Specifically, it requires two extensions that override prepareForInterfaceBuilder in two types. See MainViewController.swift in the StylishExample app for reference implementations of these extensions.

Example Project

To see Stylish in action, download the the folder “StylishExample” from this repo and open it in the latest version of Xcode. Open “Main.Storyboard” in Interface Builder and watch after a moment as the unstyled labels, buttons, and views are suddenly rendered fully styled right in Xcode.

Now, go to MainViewController.swift and in the UIView extension that overrides prepareForInterfaceBuilder(), change the line Stylish.stylesheet = Graphite() to Stylish.stylesheet = Aqua(). Then return to Main.storyboard and watch as the appearance of the scene completely changes without writing any code or even compiling the app.

Go back to MainViewController.swift and change the same line from Stylish.stylesheet = Aqua() to Stylish.stylesheet = JSON(). Now look again at Main.storyboard and once again, the whole scene will transform to reflect the new Stylesheet loaded from JSON.

At this point, you can open stylesheet.json in Xcode and start changing some of the color, font, or other values in the stylesheet, then return to Main.storyboard to watch the changes you made appear live in Interface Builder.

Or, you can create a new storyboard from scratch, add views, labels, buttons, and images and then add the already-defined styles from the sample project to those views using the inspector and watch them immediately take effect. To set styles in the storyboard, select the view you want to style, and go to the attributes inspector tab in the right panel of Xcode. This is the tab where you normally set things like color, alpha, font, etc. At the top you will see a new field you can fill out called “styles”.

These fields only appear for view classes that conform to the “Styleable” protocol and which are “@IBDesignable”. Unfortunately, it’s not possible to add “@IBDesignable” via extension, so for plain UIKit components, you have to set their custom class to the Stylish version of them: StyleableUIView, StyleableUILabel, StyleableUITextField, StyleableUITextView, StyelableUIButton, and StyleableUIImageView.

  • After you have placed some Styleable components in your blank storyboard, try adding some of these styles to buttons or plain views: PrimaryBackgroundColor, SecondaryBackgroundColor, or Rounded

  • For buttons, add the style: DefaultButton

  • For labels, try some of these HeaderText, BodyText, ThemeTitle, or HighlightedText

In Stylish, styles are not inherited, but they are additive, so you can assign multiple styles to a view by separating their names with a comma, e.g. PrimaryBackgroundColor, Rounded will first apply the style “PrimaryBackgroundColor” to the view, and then it will apply the style “Rounded”. If “Rounded” defines values for certain properties that are different than what “PrimaryBackgroundColor” defined for those same properties, the values from “Rounded” will overwrite the previous values, since it is listed after “PrimaryBackgroundColor” in the list of styles. This approach gives you very fine control over exactly how you want to combine and reuse styles for any given view.

To see an example of how to make one of your own custom views Styleable and live previewable in the storyboard with Stylish, take a look at the example inside “ProgressBar.swift”

Lastly, you can try creating some of your own defined styles by opening “Aqua.swift” or “Graphite.swift” and following the instructions and comments in either of those two files.

Creating a Style

A simple Style looks like this:

struct RoundedGray : Style {
    let propertyStylers = [
        cornerRadius.set(value:  20.0),
        backgroundColor.set(value: .gray)
    ]
} 

It gets added to a Stylesheet along with a style name like this:

class MyStylesheet : Stylesheet {
    let styles: [String: Style] = [
        "RoundedGray": RoundedGray(),
        "AnotherStyleName": AnotherStyle()
    ]
    }

Alternatively, the same Stylesheet and Style can be created in JSON like this:

{
  "styles": [
    {
      "styleName": "RoundedGray",
      "styleProperties": {
          "cornerRadius": 20.0,
          "backgroundColor": "#CCCCCC"
      }
    }

To now apply this style to a view in a Storyboard, make sure the view is set to a custom class that implements the Styelable protocol (e.g. StyleableUIView), select it on the canvas, go to the Attributes Inspector in the right-hand panel of Xcode and add the string RoundedGray to the field at the top of the panel labeled "styles”, and make sure you set Stylish.stylesheet = MyStylesheet() in the UIView extension method that overrides prepareForInterfaceBuilder() as described earlier and shows in the example project. When you press Return / Enter, the view will update immediately on the canvas.

Terminology

Style: A collection of property stylers, or values to will be applied to specific properties of that target object. Same concept as in CSS.

Stylesheet: A collection of named Styles that tie together into a theme. For example, a Stylesheet called “Default” may define Styles called “Header”, “Body”, “Highlighted”, etc. And in this Stylesheet, the “Body” style may define a value of 16 pts for the fontSize property of any targeted view. There might be another Stylesheet called “Large Type” that also defines Styles with the names “Header”, “Body”, and “Highlighted”. But in the “Large Type” Stylesheet, the “Body” style has a value of 28 pts for the fontSize property. In the app, a label with the style “Body” will be set to a font size of 16 pts when the “Default” Stylesheet is active, and 28 pts when the “Large Type” Stylesheet is active. So views are associated with fixed Style names, and Stylesheets define different sets of values for the same collection of named Styles.

Styleable: The protocol that classes must conform to to participate in the Stylish process. Stylish provides versions of common UIKit components that have already implemented Styleable as well as IBDesignable (see below). These are: StyleableUIView, StyleableUILabel, StyleableUITextField, StyleableUITextView, StyleableUIButton, and StyleableUIImageView

@IBDesignable: An attribute that can be added to any UIView subclass which indicates to Interface Builder / Xcode that it should be rendered live on the storyboard canvas.

Extending Stylish

Stylish has been designed to allow developers to extend it with additional Styleable components, including custom components. The ProgressBar component in the StylishExample application included in this repo is an example of how to do so. The process, in a nutshell, consists of:

  1. Creating new PropertyStyler types for each property you want to be able to style. These types consist of a propertyKey that indicates how the property is identified in JSON stylesheets, and a static apply function that describes how to set a value of the right type on a target object of the right type.

  2. Implementing the Styleable protocol on your custom type, which is usually just a matter of adding this property definition:

    `{ 
    @IBInspectable public var styles: String = "" {
           didSet {
               Stylish.applyStyleNames(styles, to: self)
           }
       }
    
  3. And that’s usually all it takes. While Styleable doesn’t include prebuilt Styleable types for SpriteKit or SceneKit, it’s generalized enough to be easily extended to style those kinds of objects as well.

Help

If you have any questions or need help customizing or using Stylish in your project, please open an issue in this repo, or feel free to contact me via

Twitter: @_danielhall
Email: [email protected]

Happy Styling!

Comments
  • Extending PropertyType

    Extending PropertyType

    Let's assume I want to handle myself UITextField - which is sadly not covered in stylish (BTW why?)

    I've created UITextFieldPropertySet, StyleableUITextField etc. However UITextField contains additional properties like UITextAutocapitalizationType. How can I extend JSONStyleProperty to handle this kind of property? Am I able to handle custom properties somehow?

    I can also prepare PR with 'StyleableUITextField' to extend Stylish :)

    opened by pgawlowski 4
  • Storyboards can't find styles all of a sudden

    Storyboards can't find styles all of a sudden

    This happened all of a sudden, everything was working fine before. All of the components in the storyboard are now red (which I'm used to seeing when it can't find the style). The project doesn't appear to have any errors and I've tried trimming down the styles file to rule out any errors in it, but nothing works. Is there any way to debug why this may be happening?

    I should note that when I run the application it shows all the styles just fine. If I start a fresh project or open the Stylish example project, the storyboards display styles just fine.

    opened by MatthewPatience 3
  • Runtime JSON style

    Runtime JSON style

    2 scenarios

    1. In myapp settings screen, I have a table view which lists 3 different theme names. If I select one theme, tableview dismisses and I would like to see the new theme applied (I have JSON stylesheet), is this possible using stylish ? and howto ?

    2. I would like to download JSON stylesheet from server when app starts and see this new theme applied.

    Please advise.

    opened by ypawar82 3
  • Update the mechanism for registering custom style property sets and shared styles for JSON stylesheets to use extensions instead of subclassing

    Update the mechanism for registering custom style property sets and shared styles for JSON stylesheets to use extensions instead of subclassing

    Currently, in order to use custom style properties and components in JSON, the app needs to subclass JSONStylesheet and register the custom property sets.

    To avoid inheritance and be a little more Swift-y, let's change this mechanism to be having the app add an extension to JSONStylesheet with the custom property sets to register.

    opened by daniel-hall 2
  • Apply styles to non conformed

    Apply styles to non conformed "Styleable" components

    Problem:

    I needed the ability to apply styles to controls that I was unable to specify StyleableUI*** on. I've been using the Eureka form framework for dynamic forms.

    Soluton:

    I'll start off saying that this is a hack but it did the job :)

    Created a custom styler that wrapped Stylish.AnyPropertyStyler:

    *since most controls inherit from UIView, we can get away with something like this.

    public struct ThemeStyler {
        private let propertyValueApplicator: (UIView) -> ()
        let propertyStyle: AnyPropertyStyler
        
        init(styler: AnyPropertyStyler, propertyValueApplicator: @escaping (UIView) -> ()) {
            self.propertyStyle = styler
            self.propertyValueApplicator = propertyValueApplicator
        }
        
        func apply(to target: UIView) {
            propertyValueApplicator(target)
        }
        
        func apply(to target: UILabel) {
            propertyValueApplicator(target)
        }
        
        func apply(to target: UITextView) {
            propertyValueApplicator(target)
        }
        
        func apply(to target: UITextField) {
            propertyValueApplicator(target)
        }
    }
    
    

    I then extended Stylish.PropertyStyler":

    • Notice this only serves the purpose of creating a propertyValueApplicator that conforms to UIView instead of Stylish.Styleable
    public extension PropertyStyler {
        static func setStyle(value: PropertyType?) -> ThemeStyler {
            let styler = set(value: value)
            return ThemeStyler(styler: styler, propertyValueApplicator: { if let target = $0 as? TargetType { Self.apply(value: value, to: target) } })
        }
    }
    

    Since all stylers are contained within a style I had to create my own like this:

    protocol ThemeStyle: Stylish.Style {
        var stylers: [ThemeStyler] { get }
    }
    
    extension ThemeStyle {
    	// compatibility with Stylish (default)
        var propertyStylers: [AnyPropertyStyler] {
            get {
                return stylers.map { $0.propertyStyle }
            }
        }
    }
    

    Then in my custom theme I added:

    class Theme : Stylesheet {
       ...
       ...
       
       struct MyCustomStyle : ThemeStyle {
            var stylers: [ThemeStyler] = [
            	backgroundColor.setStyle(value: .red)
            ]
        }
        
        static func applyStyleNames(_ styles: [String], to target: UIView?) {
            guard let targetView = target else {
                return
            }
            var styleClasses: [ThemeStyle] = []
            for style in styles {
                if let styleClass = Stylish.stylesheet?.styles[style] {
                	// since styles can be populated from json 
                    // check for our custom class
                    if let themeStyle = styleClass as? ThemeStyle {
                        styleClasses.append(themeStyle)
                    }
                }
            }
            styleClasses.forEach{ $0.stylers.forEach { $0.apply(to: targetView) } }
        }
    }
    
    

    I can now use this like so:

    Theme.applyStyleNames(["MyCustomStyle"], self.someUIView)

    Thoughts for next version?

    opened by codelance 1
  • Setting UIButton.title font

    Setting UIButton.title font

    I have a style for UIButtons that requires the use of a custom font. I was thinking I would set UIButton.title to a certain font ... but that doesn't seem to be possible. Do you have an example of how to set the font of a UIButton title?

    opened by adamn 1
  • Added support for Constant values that can be reused in the stylesheet

    Added support for Constant values that can be reused in the stylesheet

    • Migrated to Swift 5. Made StyleableComponents a public header
    • Added support for constant values in the JSON file defined in a new object at the same level of the styles object
        "constants": {
            "PrimaryColor" : "#FF5A5F",
            "Header5Font" : {
                "name": "CircularStd-Bold",
                "size": 18.0
            }
        }
    

    That can be later reused in the styles dictionary as following:

            {
                "styleName": "Primary",
                "styleProperties": {
                    "backgroundColor": "$PrimaryColor"
                }
            },
            {
                "styleName": "Header5",
                "styleProperties": {
                    "font": "$Header5Font",
                    "textColor": "#3f444c"
                }
            }
    
    opened by lucaslt89 0
  • Add a bundle parameter for PropertyStyler apply methods / applicators…

    Add a bundle parameter for PropertyStyler apply methods / applicators…

    …, and a bundle property to the Stylesheet protocol

    The goal is to allow Stylesheets to be linked to assets in their own bundle. So after creating a Stylesheet, it can be distributed in a framework or library that also includes an asset catalog with named images, colors, etc. and when property stylers go to apply those assets to a target, they will have the right bundle to pull them from.

    opened by daniel-hall 0
  • Exposed static registration methods for custom properties, sets, and …

    Exposed static registration methods for custom properties, sets, and …

    …classes instead of exposing the static vars directly.

    This is to prevent multiple clients of Stylish in the same final application from overwriting each other’s custom settings

    opened by daniel-hall 0
  • Updated for Swift 3 plus improvements

    Updated for Swift 3 plus improvements

    • Error messaging added for JSON parsing
    • Load the latest version of stylesheet.json from Documents directory or bundle
    • Implemented copy-on-write for StyleClass property storage so changes to one copy of a Style Class instance doesn't effect other copies
    • Method renaming to better adhere to Swift 3 API design guidelines
    opened by daniel-hall 0
  • Unable to use with Swift Package Dependency

    Unable to use with Swift Package Dependency

    Hi, Using this framework, Awesome framework. But need to update the using "Swift Package Dependency", Tried to use it but unable to install getting below error.

    Showing Recent Messages /Package.swift has no Package.swift manifest for version 1.0.2 in https://github.com/ThomasHaz/Stylish

    opened by pathanrasool 0
  • Feature: Swift Package Manager support

    Feature: Swift Package Manager support

    • Added support Swift Package Manager by adding Package.swift.
    • Fixed some warnings with Stylish.xcodeproj and updated the project to recommended settings.
    • Updated .gitignore.
    • Updated README.md.
    opened by arnold-plakolli 0
  • Cocoapods integration

    Cocoapods integration

    Hi,

    thanks for this great framework! Will you make it available on cocoapods? It would certainly make integration into new projects easier, as well as being much less painful than using submodules.

    opened by davidganster 5
Releases(v0.9.4)
  • v0.9.4(Jun 23, 2019)

    • You can now define and reuse constant values inside a JSON stylesheet, thanks to @lucaslt89

      Example:

      { 
         "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

    Source code(tar.gz)
    Source code(zip)
  • 0.9.3(Nov 4, 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.

    Source code(tar.gz)
    Source code(zip)
  • v0.9.2(Oct 3, 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:

    primaryBackground secondaryBackground primaryTextOnPrimaryBackground secondaryTextOnPrimaryBackground primaryTextOnSecondaryBackground secondaryTextOnSecondaryBackground

    etc.

    You can now have two stylesheets:

    ####Primary Stylesheet background primaryText secondaryText

    ####Secondary Stylesheet background primaryText secondaryText

    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!

    Source code(tar.gz)
    Source code(zip)
  • v0.9.1(Sep 29, 2018)

  • v0.9(Nov 8, 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.

    IMPORTANT: THIS IS A BREAKING VERSION

    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.

    Source code(tar.gz)
    Source code(zip)
  • v0.75(Oct 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?

    Source code(tar.gz)
    Source code(zip)
  • v0.7(Oct 1, 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

    Source code(tar.gz)
    Source code(zip)
  • v0.6(Sep 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
    Source code(tar.gz)
    Source code(zip)
  • v0.5(Jun 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
    Source code(tar.gz)
    Source code(zip)
Owner
Daniel Hall
Working on great user experiences and the frameworks & tools to build them faster
Daniel Hall
The Swift code generator for your assets, storyboards, Localizable.strings, … — Get rid of all String-based APIs!

SwiftGen SwiftGen is a tool to automatically generate Swift code for resources of your projects (like images, localised strings, etc), to make them ty

null 8.3k Dec 31, 2022
Localize is a framework writed in swift to localize your projects easier improves i18n, including storyboards and strings.

Localize Localize is a framework written in swift to help you localize and pluralize your projects. It supports both storyboards and strings. Features

Andres Silva 279 Dec 24, 2022
Super lightweight library that helps you to localize strings, even directly in storyboards!

Translatio Example To run the example project, clone the repo, and run pod install from the Example directory first. Requirements iOS 9 or higher. Swi

Andrea Mario Lufino 19 Jan 29, 2022
Custom segue for OSX Storyboards with slide and cross fade effects (NSViewControllerTransitionOptions)

CustomSegue Custom segue for OSX Storyboards. Slide and cross fade effects, new customized window. class MyViewController: NSViewController { overr

Eric Marchand 123 May 21, 2022
The Swift code generator for your assets, storyboards, Localizable.strings, … — Get rid of all String-based APIs!

SwiftGen SwiftGen is a tool to automatically generate Swift code for resources of your projects (like images, localised strings, etc), to make them ty

null 8.3k Jan 3, 2023
Play with Xcode storyboards...

Storyboards In this repo, we will be playing with storyboards. Add Table View and Collection Views and show some data using the data source and delega

null 0 Oct 14, 2021
A Swift mixin for reusing views easily and in a type-safe way (UITableViewCells, UICollectionViewCells, custom UIViews, ViewControllers, Storyboards…)

Reusable A Swift mixin to use UITableViewCells, UICollectionViewCells and UIViewControllers in a type-safe way, without the need to manipulate their S

Olivier Halligon 2.9k Jan 3, 2023
Swift CLI for strong-typing images, colors, storyboards, fonts and localizations

Shark Shark is a Swift command line tool that generates type safe enums for your images, colors, storyboards, fonts and localizations. Because Shark r

Kaan Dedeoglu 377 Dec 1, 2022
Generate a constants file by grabbing identifiers from storyboards in a project.

sbconstants Generate a constants file by grabbing identifiers from storyboards in a project. Installation $ gem install sbconstants Usage For automate

paul.s 310 Sep 9, 2022
Xcode storyboards diff and merge tool.

StoryboardMerge Storyboard diff and merge tool which: compares and merges two storyboard files, provides an automatic merge-facility, The storyboardin

null 238 Sep 12, 2022